等待 return 主块,直到其封装的子块完成

Waiting to return main block until its encapsulated children are finished

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

我发现自己处于这样一种情况,即我 运行 在异步 GET 块中使用 for 循环,它本身包含一个 'secondary'/child GET 块,如下所示:

 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)")
    })

希望每个辅助块都添加到一个 returnArray,主块 returns 作为其完成处理程序。但是,我希望仅当所有辅助块都完成 returning/adding 到 returnArray.

时,主块才执行此完成(和相应的数组)

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

非常感谢您的指导!

为了在一系列异步任务完成后触发一段代码,我们一般使用"dispatch groups."所以创建一个调度组,"enter"每次请求前的组,"leave"' 在每个完成块中,然后创建一个调度 "notify" 块,当所有 "enter" 调用由 "leave" 调用平衡时调用该块:

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 的处理。您可以创建一个自定义队列来协调它,或者像我上面那样使用主队列。