何时使用主队列

时间:2017-04-26 16:21:21

标签: ios swift queue grand-central-dispatch

我知道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)时,我应该将它包装在主队列中吗?

2 个答案:

答案 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()