dispatch_get_main_queue 卡死的问题
这两天做项目的过程中遇到dispatch_get_main_queue卡死的问题,已解决,在此记录下。
其主要现象是,我有一个view,在创建的时候需要刷新,而这个view是在windowDidLoad里面创建的,我在子线程里面调用dispatch_sync(dispatch_get_main_queue(), ^{})方法刷新了view,结果window一打开,就出现了卡死现象。
其主要原因是主线程消息队列引起的,dispatch_get_main_queue()是一个串行的队列,即先进先出,系统维护的dispatch_get_main_queue()执行viewDidLoad,先进栈,所以应该是viewDidLoad执行完毕后再执行其它任务,但是现在,viewDidLoad里面又调用了dispatch_sync(dispatch_get_main_queue(), ^{}),所以viewDidLoad会等待dispatch_sync调用的dispatch_get_main_queue()执行完毕,而dispatch_sync调用的dispatch_get_main_queue()又在等待viewDidLoad执行完毕,就这样进入了死循环。
我尝试先让viewDidLoad执行完,然后再创建我的view,结果还是不行,应该是这种冲突不止在viewDidLoad里面发生,在其它刷新view时,系统维护的dispatch_get_main_queue()和自己维护的dispatch_get_main_queue()都很容易产生冲突。
最后换了一个处理方法,抛弃了dispatch_get_main_queue(),使用performSelectorOnMainThread函数,结果就没有问题了。
dispatch_get_main_queue是在the main run loop里面的,会有block;而performSelectorOnMainThread是在the default run loop mode里面的,会有一个模式切换。想必也是这个原因才不会引起的卡死吧。
另外,还有dispatch_async异步操作,也不会发生锁死,比如:
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// 处理
dispatch_async(dispatch_get_main_queue(), ^{
// 更新UI
});
});
再来简单解释下两个队列:
dispatch_get_main_queue:获取主队列,会将任务插入主线程的RunLoop当中去执行,是个串行队列,可以使用它来更新UI。
dispatch_get_global_queue:是一个全局的并行队列,有高、默认、低和后台4个优先级,由第一个参数决定,第二个参数是保留字段备用,一般为0。