Multithreading 从for循环中的异步请求返回
我试图从我的RestAPI获取数据,特别是我获取一个整数数组(来自其他用户的id),我想循环通过这个数组并从所有其他客户下载数据。代码的简化版本如下所示Multithreading 从for循环中的异步请求返回,multithreading,swift,for-loop,asynchronous,Multithreading,Swift,For Loop,Asynchronous,我试图从我的RestAPI获取数据,特别是我获取一个整数数组(来自其他用户的id),我想循环通过这个数组并从所有其他客户下载数据。代码的简化版本如下所示 func asyncFunc(completion: (something:[Int])->Void){ //Get a json Array asynchonous from my RestAPI let jsonArray = [1,2,3,4,5] var resultingArray:[Int] = [] fo
func asyncFunc(completion: (something:[Int])->Void){
//Get a json Array asynchonous from my RestAPI
let jsonArray = [1,2,3,4,5]
var resultingArray:[Int] = []
for myThing in jsonArray{
anotherAsyncFunc(myThing, completion: { (somethingElse) -> Void in
resultingArray.append(somethingElse)
})
}
}
func anotherAsyncFunc(data:Int, completion: (somethingElse:Int)->Void){
//Get some more jsonData from RestApi/data
let myLoadedData:Int = data*13356
completion(somethingElse: myLoadedData)
}
如何使我的asyncFunc
返回一个数组,其中包含它从第二个(内部)异步请求中获得的所有项
我已经尝试获取RESTAPI第一次请求的数组的计数,并使用while循环“阻塞”UI线程,查看“新”数组是否收集了所有数据(计数等于第一次请求的数组的计数)。这有两个主要缺点,主要是它会阻塞UI线程,而且,如果在我从其他用户(内部异步请求)获取数据时数据连接断开,它会导致应用程序失败和崩溃,导致while循环永远无法完成
我的问题是,我如何使用完成处理程序返回它应该返回的所有数据,而不阻塞主线程和/或担心数据连接丢失的错误时间。您可以使用调度组通知。因此,创建一个调度组,为数组中的每个项目输入组,在
anotherAsyncFunc
asynchronous进程的完成处理程序中退出,然后创建一个通知,当所有的dispatch\u group\u enter
调用被相应的dispatch\u group\u leave
调用抵消时,该通知将触发最终的completion
关闭:
func asyncFunc(completion: (something:[Int])->Void){
//Get a json Array asynchonous from my RestAPI
let jsonArray = [1,2,3,4,5]
var resultingArray:[Int] = []
let group = dispatch_group_create()
for myThing in jsonArray {
dispatch_group_enter(group)
anotherAsyncFunc(myThing) { somethingElse in
resultingArray.append(somethingElse)
dispatch_group_leave(group)
}
}
dispatch_group_notify(group, dispatch_get_main_queue()) {
completion(something: resultingArray)
}
}
注意,您需要确保将更新同步到
resultingArray
,以确保anotherAsyncFunc
正在执行。最简单的方法是确保它将更新发送回主队列(如果您的RESTAPI还没有这样做)
这只是一个例子。您可以使用您想要的任何同步机制,但请确保相应地在
resultingArray
上同步更新。谢谢,我不知道这个函数。工作得很有魅力!但是,这将如何处理下载过程中丢失的数据连接?在Swift 1.2中,您通常会在anotherAsyncFunc
的completion
块参数中添加一个可选错误参数,并将somethingElse
设为可选,只要确保调用completion
块,无论是否成功(根据需要设置错误或somethingElse
引用)。
func anotherAsyncFunc(data:Int, completion: (somethingElse:Int)->Void){
//Get some more jsonData from RestApi/data asynchronously
let myLoadedData:Int = data*13356
dispatch_async(dispatch_get_main_queue()) {
completion(somethingElse: myLoadedData)
}
}