我知道UI的任何更新都应该使用以下语法在主队列中运行:
dispatch_async(dispatch_get_main_queue()) {
UI update code here
}
这些其他案件怎么样?
在我的viewDidLoad()中,我有代码来设置导航栏和工具栏的样式,如下所示:
let nav = self.navigationController?.navigationBar
nav?.barStyle = UIBarStyle.Default
nav?.tintColor = UIColor.blackColor()
nav?.barTintColor = UIColor(red:133.0/255, green:182.0/255, blue:189.0/255, alpha:1.0)
let toolBar = self.navigationController?.toolbar
toolBar?.barTintColor = UIColor(red:231/255, green:111/255, blue:19.0/255, alpha:1.0)
toolBar?.tintColor = UIColor.blackColor()
我是否应该将此代码包装在主队列中?
在我的tableView cellForRowAtIndexPath函数中,我是否应该包装所有代码以设置主队列中每个表格单元格的UI?
当我提出一个新的模态控制器(self.presentViewController(modalController,animated:true,completion:nil)时,我应该将它包装在主队列中吗?
答案 0 :(得分:6)
你所有问题的答案都是“不”
除非文档中另有说明,否则将在主队列中调用所有UIKit函数。
通常,在使用在后台队列上运行的完成处理程序调用异步func之后,您需要专门在主队列上运行。有点像...
// downloadImage is some func where the
// completion handler runs on a background queue
downloadImage(completion: { image in
DispatchQueue.main.async {
self.imageView.image = image
}
})
答案 1 :(得分:2)
是的,如果函数已经在后台队列上异步执行,那么调用主队列是你应该只需要做的事情。而且这种情况本身并不会发生。
像Ashley所说,UIKit方法是从主队列中自动调用的 - 它们就是这样的。因此,有理由认为某些框架具有从后台队列自动调用的方法。
我知道URLSession的dataTask的恢复功能会自动在后台队列上执行(因此应用程序不会因网络连接而变慢),表示后执行的完成处理程序ALSO在后台队列上工作。这就是为什么在完成处理程序中发生的任何UI更新肯定需要在主队列上进行调用的原因。
let dataTask = URLSession.shared.dataTask(with: request) {
// begin completion handler
(data, response, error) in
guard error == nil else { print("error \(error.debugDescription)"); return }
guard let data = data else { print("no data"); return }
do {
if let json = try JSONSerialization.jsonObject(with: data, options: .allowFragments) as? [[String: Any]] {
print("sending returned JSON to handler")
self.responseHandler.handleAPIResponse(jsonArray: json)
>>>> DispatchQueue.main.async { <<<<
self.tableView.reloadData()
}
}
} catch {
print("get tasks JSONSerialization error")
}
}
dataTask.resume()