swift - 等待返回主 block ,直到其封装的子 block 完成

标签 swift rest asynchronous network-programming

我对 Swift 中的异步网络还很陌生,目前正在使用 SwiftHTTP运行 HTTP GET 请求的库。

我发现自己处于这样一种情况,即我在异步 GET block 中运行 for 循环,该 block 本身包含一个“辅助”/子 GET block ,如下所示:

 request.GET("https://", parameters: nil, success: { (response: HTTPResponse) in
        if response.responseObject != nil {

            var returnArray = [returnObject]() // ***

            // responseObject is an array of 'results', thus loop through and perform a secondary GET for each 'result'

                    for result in response.responseObject {

                        secondaryRequest.GET(result["url"], parameters: nil, success: { (secondaryResponse: HTTPResponse) in
                            if secondaryResponse.responseObject != nil {

                                // *** add secondary repsonseObject to main 'returnArray', created at the top of the first block
                                returnArray.append(secondaryResponse.responseObject!)

                            }


                            },failure: {(error: NSError, secondaryResponse: HTTPResponse?) in
                                println("got an error: \(error)")
                        })

                    }


                completion(returnArray) // HOW TO ONLY RETURN WHEN ALL SECONDARY LOOPS HAVE FINISHED ADDING TO THE RETURN ARRAY???

            }

        }

        }, failure: {(error: NSError, reponse: HTTPResponse?) in
            println("got an error: \(error)")
    })

希望每个辅助 block 都添加到主 block 作为其完成处理程序返回的 returnArray 足够清楚。但是,我希望主 block 仅在所有辅助 block 完成返回/添加到 returnArray 时才执行此完成(和相应的数组)。

如果不执行我自己的 hacky 选项(比如,用 NSTimer 等待——我能听到那个叹息!:'),或者将每个二次迭代添加到一个重要的外部函数,我真的不知道从哪里开始每次添加直到达到预定义的循环阈值)。

非常感谢您的指导!

最佳答案

为了在完成一系列异步任务时触发一段代码,我们通常使用“调度组”。所以创建一个调度组,在每个请求之前“进入”该组,在每个完成 block 中“离开”,然后创建一个调度“通知” block ,当所有“进入”调用由“平衡”时调用离开”电话:

request.GET("https://", parameters: nil, success: { response in
    if response.responseObject != nil {
        let group = dispatch_group_create()
        var returnArray = [ReturnObject]()

        for result in response.responseObject {
            dispatch_group_enter(group)
            secondaryRequest.GET(result["url"], parameters: nil, success: { secondaryResponse in
                dispatch_async(dispatch_get_main_queue()) {
                    if secondaryResponse.responseObject != nil {
                        returnArray.append(secondaryResponse.responseObject!)
                    }
                    dispatch_group_leave(group)
                }
            },failure: { error, secondaryResponse in
                println("got an error: \(error)")
                dispatch_group_leave(group)
            })
        }

        dispatch_group_notify(group, dispatch_get_main_queue()) {
            completion(returnArray)
        }
    }
}, failure: {error, reponse in
    println("got an error: \(error)")
})

请注意,由于 GET 完成处理程序关闭发生在后台队列上,因此您需要同步 returnArray 的处理。您可以创建一个自定义队列来协调它,或者像我上面所做的那样只使用主队列。

关于swift - 等待返回主 block ,直到其封装的子 block 完成,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30156732/

相关文章:

javascript - javascript for 循环内的异步过程

swift - 循环和范围运算符的基准

使用 Parse 平台的 iOS 推送通知 - didRegisterForRemoteNotificationsWithDeviceToken - 从未调用

java - 如果未执行 JAXB 模型中的 setter,则不显示 XML 元素

java - Java Rest 服务范围内的静态变量

javascript - 嵌套回调

share - 'NSSecureCoding !' is not a subtype of ' NSURL' 在尝试替换闭包参数类型时使用 Swift

swift 2.0,Alamofire : Set cookies in HTTP Post Request

rest - Delphi - 将 header 值传递给 REST 服务

javascript - AngularJS - "Chaining promises"以及其间的其他函数