使用 NSURLSession 发出同步请求

Make sync request with NSURLSession

我在另一个线程中调用了一些函数:

dispatch_async(dispatch_get_global_queue(priority, 0)) {
     self.someFunction()
}

然后在这个函数中我想做同步请求:

let config = NSURLSessionConfiguration.defaultSessionConfiguration()
let session = NSURLSession(configuration: config)
let dataSemaphore = dispatch_semaphore_create(0)

let task = session.dataTaskWithRequest(urlRequest, completionHandler: { (data, response, error) in
guard let responseData = data else {
    print("Error: did not receive data")
    return
}
guard error == nil else {
    print("error calling GET")
    print(error)
    return
    }
    print("ASYNC")
})
task.resume()

dispatch_semaphore_wait(dataSemaphore, DISPATCH_TIME_FOREVER)

print("SYNC")

但是线程在这一行停止dispatch_semaphore_wait(dataSemaphore, DISPATCH_TIME_FOREVER)

您从未向信号量发出信号,请将其放在完成处理程序的末尾:

dispatch_semaphore_signal(dataSemaphore)

虽然这里的另一个答案在技术上是正确的,但我觉得有必要 post 第二个答案,询问 为什么 你这样做....

同步网络几乎从来不是做任何事情的正确方法。相反,你真的应该让函数的其余部分成为一个块,在请求完成时获取 运行。

在技术上可以为异步 API 创建一个同步包装器这一事实并不能否定这样一个事实,即这样做会阻塞 运行 正在执行此代码的任何线程,所以除非你在您需要对网络请求执行某种严格排序的情况下,同步请求通常不是一个好主意,即便如此,它们也不是 主意。