死锁主要是因为,同步函数必须等待任务完成才能返回,而一旦在一个串行队列中调用同步派发函数往相同队列派发任务时,就会出现派发函数等待任务完成,任务等待位于队列中更靠前的派发函数完成这种相互等待的尴尬情况。
案例与分析
- 案例一:
NSLog(@"1"); // 任务1
dispatch_sync(dispatch_get_main_queue(), ^{ NSLog(@"2"); // 任务2});
NSLog(@"3"); // 任务3
结果,控制台输出:1
分析:
- dispatch_sync表示是一个同步线程;
- dispatch_get_main_queue表示运行在主线程中的主队列;
- 任务2是同步线程的任务。
首先执行任务1,这是肯定没问题的,只是接下来,程序遇到了同步线程,那么它会进入等待,等待任务2执行完,然后执行任务3。但这是队列,有任务来,当然会将任务加到队尾,然后遵循FIFO原则执行任务。那么,现在任务2就会被加到最后,任务3排在了任务2前面,问题来了:
任务3要等任务2执行完才能执行,任务2由排在任务3后面,意味着任务2要在任务3执行完才能执行,所以他们进入了互相等待的局面。【既然这样,那干脆就卡在这里吧】这就是死锁。