如何使用异步方法遍历数组,并以正确的顺序将 return 值放入数组中

How to iterate thru array with asynchronous method, and put return values into an array in the PROPER order

我有一个包含 x 个值(不超过 25)的数组。每个值都对应一个我希望从远程端点检索的项目对象。我使用以下方法为每个相应的标识符检索项目对象...

func getValues(valueIDs: [Int]){

    var values = [Item]()
    let group = dispatch_group_create()

    for i in 0...valueIDs.count-1 {
        dispatch_group_enter(group)

        Item.special(valueIDs[i], completion: ({ result in
            if let value = result.response.result {
                values.append(value)
                dispatch_group_leave(group)
            }
        })
        )
    }

    dispatch_group_notify(group, dispatch_get_global_queue(QOS_CLASS_DEFAULT, 0)) {
        print("the values are \(values)")
    }

}

该方法是异步的,因此每次在 for 循环 return 中调用它都会立即完成,并且循环会在任何值 return 之前完成对所有值的迭代。当所有呼叫都已 return 时,我会使用 dispatch_group 得到通知。

我遇到的问题是,我需要将检索到的值放入我的数组中,并且顺序与它们被调用的顺序相同。目前,它们在 returned 时被附加到数组中,因此它们是随机排序的。我不想将所有呼叫放在一个串行队列中并让它们互相等待,那样会花费太长时间。任何建议都会很棒!!

检查这是否有效,声明一个固定长度的数组并按索引访问数组元素:

func getValues(valueIDs: [Int]){

    var items = [Item?](count: valueIDs.count, repeatedValue: nil)
    let group = dispatch_group_create()

    for i in 0...valueIDs.count-1 {
        dispatch_group_enter(group)

        Item.special(valueIDs[i], completion: ({ result in
            if let value = result.response.result {
                items[i] = value
                dispatch_group_leave(group)
            }
        })
        )
    }

    dispatch_group_notify(group, dispatch_get_global_queue(QOS_CLASS_DEFAULT, 0)) {
        print("the values are \(items)")
    }

}

@muneeb 的回答是标准方法。对于另一种可能更具可读性的方法,使用字典将索引映射到项目。

func getValues(valueIDs: [Int]) {

    var keyedValues = [Int: Item]()
    let group = dispatch_group_create()

    for i in 0 ..< valueIDs.count {
        dispatch_group_enter(group)

        Item.special(valueIDs[i]) { result in
            if let value = result.response.result {
                keyedValues[i] = value
                dispatch_group_leave(group)
            }
        }
    }

    dispatch_group_notify(group, dispatch_get_global_queue(QOS_CLASS_DEFAULT, 0)) {
        var values = [Item]()

        for i in 0 ..< valueIDs.count {
            values.append(keyedValues[i]!)
        }

        print("the values are \(values)")
    }

}