[英]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.