如何使用异步方法遍历数组,并以正确的顺序将 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)")
}
}
我有一个包含 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)")
}
}