swift 3.0中跟踪一批HTTP请求的解决方案
A solution to track a batch of HTTP requests in swift 3.0
我在 iOS 10.0 下使用 swift 3.0 运行,我想编写一些代码,在满足批处理条件时触发。
for i in 0 ..< rex {
async code, disappears and does it stuff
}
假设异步代码是 URL 请求的集合,当我循环遍历它们时,基本上就是背景。现在如何在 "rex" 请求完成后触发更多代码?
我想过设置一个定时器,每秒看一次,但肯定不是个好办法。
我想启动另一个线程来简单地观察正在收集的数据,并在其配额已满时触发,但这确实比计时器更糟糕。
我正在考虑在每个 URL 请求的末尾添加一个测试,看看它是否是最后一个完成并使用 NotificationCenter 的,但这是最佳解决方案吗?
所以我很确定你想要什么 found here. Basically you want to use GCD and have a completion closure. It's one line of code, which always makes me giggle. A longer post on the topic is here。
您要查找的是 NSOperationQueue
(或 Swift 3 中的 OperationQueue
)。这是一个 Swift tutorial (might be a bit out of date). Here's Apple's documentation on it -- 在 Swift 3 中,他们删除了所有 NS 前缀,所以它是 OperationQueue
/ Operation
.
基本上,您应该将每个 URL 任务作为 Operation
添加到 OperationQueue
,并且每个 "done" Operation
URL 任务作为依赖项,并将其添加到队列中。然后,一旦你所有的 URL 任务完成,它就会调用你的完成操作,你可以设置它来做任何你想做的事情。
您可能需要对 Operation
进行子类化,以便正确更新 isExecuting
和 isFinished
属性。 This question may be of some help here。
虽然 OperationQueue
(又名 NSOperationQueue
)在许多情况下是一个不错的选择,但它不适合您的用例。问题是 URL 请求被异步调用。您的 NSOperation
将在您收到网络服务的响应之前完成。
改用DispatchGroup
let group = DispatchGroup()
// We need to dispatch to a background queue because we have
// to wait for the response from the webservice
DispatchQueue.global(qos: .utility).async {
for i in 0 ..< rex {
group.enter() // signal that you are starting a new task
URLSession.shared.dataTask(with: urls[i]) { data, response, error in
// handle your response
// ....
group.leave() // signal that you are done with the task
}.resume()
}
group.wait() // don't ever call wait() on the main queue
// Now all requests are complete
}
我在 iOS 10.0 下使用 swift 3.0 运行,我想编写一些代码,在满足批处理条件时触发。
for i in 0 ..< rex {
async code, disappears and does it stuff
}
假设异步代码是 URL 请求的集合,当我循环遍历它们时,基本上就是背景。现在如何在 "rex" 请求完成后触发更多代码?
我想过设置一个定时器,每秒看一次,但肯定不是个好办法。
我想启动另一个线程来简单地观察正在收集的数据,并在其配额已满时触发,但这确实比计时器更糟糕。
我正在考虑在每个 URL 请求的末尾添加一个测试,看看它是否是最后一个完成并使用 NotificationCenter 的,但这是最佳解决方案吗?
所以我很确定你想要什么 found here. Basically you want to use GCD and have a completion closure. It's one line of code, which always makes me giggle. A longer post on the topic is here。
您要查找的是 NSOperationQueue
(或 Swift 3 中的 OperationQueue
)。这是一个 Swift tutorial (might be a bit out of date). Here's Apple's documentation on it -- 在 Swift 3 中,他们删除了所有 NS 前缀,所以它是 OperationQueue
/ Operation
.
基本上,您应该将每个 URL 任务作为 Operation
添加到 OperationQueue
,并且每个 "done" Operation
URL 任务作为依赖项,并将其添加到队列中。然后,一旦你所有的 URL 任务完成,它就会调用你的完成操作,你可以设置它来做任何你想做的事情。
您可能需要对 Operation
进行子类化,以便正确更新 isExecuting
和 isFinished
属性。 This question may be of some help here。
虽然 OperationQueue
(又名 NSOperationQueue
)在许多情况下是一个不错的选择,但它不适合您的用例。问题是 URL 请求被异步调用。您的 NSOperation
将在您收到网络服务的响应之前完成。
改用DispatchGroup
let group = DispatchGroup()
// We need to dispatch to a background queue because we have
// to wait for the response from the webservice
DispatchQueue.global(qos: .utility).async {
for i in 0 ..< rex {
group.enter() // signal that you are starting a new task
URLSession.shared.dataTask(with: urls[i]) { data, response, error in
// handle your response
// ....
group.leave() // signal that you are done with the task
}.resume()
}
group.wait() // don't ever call wait() on the main queue
// Now all requests are complete
}