[英]URLSession.shared.dataTask freezes the UI
我正在为 iOS 制作一个Swift
应用程序,但我提出的请求有问题。
此请求每 3 到 5 秒发出一次,主体是 5k 行 JSON(总共约 130k 个字符),用于刷新UITableView
。 问题是每次.dataTask
用于此特定请求时,应用程序都会冻结,然后在发出请求后正常运行。
“冻结”是指在滚动长 UITableView 时检测到它。 即使是一个小的滚动列表也会冻结。
我首先怀疑UITableView
的更新,但我添加了一个小的“hack”,它在滚动时禁用UITableView
的更新,如下所示:
func scrollViewWillBeginDragging(_ scrollView: UIScrollView) {
print("started scrolling")
self.currentlyScrolling = true
}
func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
print("stopped scrolling")
self.currentlyScrolling = false
}
它不起作用。
我的问题是:我认为 dataTask 不在主线程中运行。 但我不确定。 我该如何检查? 另外,我如何确定 dataTask 是 async ?
这是dataTask
代码的样子:
let task = URLSession.shared.dataTask(with: req) { data, response, err in
guard let data = data, err == nil else {
// error
return
}
if let resp = try? JSONSerialization.jsonObject(with: data) {
// success
}
}
task.resume()
然而,请注意,它只在 JSONSerialization 之前冻结,而不是之后,所以我想这不是导致冻结的原因。
URLSession.shared.dataTask
在后台线程中运行,您可以移动JSONSerialization
,如果您正在更新 UI 移动所有在主线程中
let task = URLSession.shared.dataTask(with: req) { data, response, err in {
// HERE YOU ARE IN BACKGROUND THREAD, see print result in debug area
print("You are on \(Thread.isMainThread ? "MAIN" : "BACKGROUND") thread.")
guard let data = data, err == nil else { return }
if let resp = try? JSONSerialization.jsonObject(with: data) {
DispatchQueue.main.async {
print("Now moved to \(Thread.isMainThread ? "MAIN" : "BACKGROUND") thread")
// success, ANY UI UPDATES MUST BE MADE HERE
}
}
}
你的 JSON 解析应该在后台线程上,所以这个解析操作不会阻塞主线程上的其他东西,比如 UI。
以下是使用在主线程上调用的完成块的示例
func myApiTask(with request: URLRequest, completion:@escaping (_ data: Any?) -> Void) {
let task = URLSession.shared.dataTask(with: request) { data, response, error in
var resp: Any?
defer {
DispatchQueue.main.async{ completion(resp) }
}
if data == nil && error == nil {
resp = try? JSONSerialization.jsonObject(with: data!)
} else {
// error handling
}
}
}
用法
myApiTask(with: req) { data in
// you are on main thread
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.