基本上我有一些JSON数据,我希望从一堆URL(所有来自同一主机)中检索,但是我只能每2秒钟大致请求这些数据,一次只能请求一个,或者我将是“时间”禁止“从服务器 . 正如你在下面看到的那样;虽然URLSession非常快,但当我有大约700个网址可以通过时,它几乎可以立即被禁止 .
我将如何在URLSession中创建一个队列(如果它的功能支持它)并且让它与我的主线程异步工作;让它在自己的线程上连续工作,并且只有在完成上一个请求2秒后才尝试队列中的每个项目?
for url in urls {
get(url: url)
}
func get(url: URL) {
let session = URLSession.shared
let task = session.dataTask(with: url, completionHandler: { (data, response, error) in
if let error = error {
DispatchQueue.main.async {
print(error.localizedDescription)
}
return
}
let data = data!
guard let response = response as? HTTPURLResponse, response.statusCode == 200 else {
DispatchQueue.main.async {
print("Server Error")
}
return
}
if response.mimeType == "application/json" {
do {
let json = try JSONSerialization.jsonObject(with: data) as! [String: Any]
if json["success"] as! Bool == true {
if let count = json["total_count"] as? Int {
DispatchQueue.main.async {
self.itemsCount.append(count)
}
}
}
} catch {
print(error.localizedDescription)
}
}
})
task.resume()
}
3 回答
递归解决了这个问题
最简单的方法是执行递归调用:
想象一下,你的网址中有数组 .
在最初执行循环的位置,将其替换为单个调用
get(url:)
.self.get(urls[0])
然后在
self.itemsCount.append(count)
之后立即在响应闭包处添加此行:使
DispatchQueue
在线程上运行代码 . 您不需要在主线程上执行此操作 . 所以,顺便说一下,你的
get(url: url)
功能并不是那么好 .我建议你学习
GCD
(用于线程)和escaping closure
(用于完成处理程序)的概念 .GCD:https://www.raywenderlich.com/148513/grand-central-dispatch-tutorial-swift-3-part-1
逃离关闭:https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/Closures.html#//apple_ref/doc/uid/TP40014097-CH11-ID546