2018.8.3
问题分析#
使用dispatch_sync的时候要小心谨慎,稍不注意就会导致死锁问题,先看两个典型的案例:
案例一
- (void)deadlock1 {
dispatch_queue_t queue = dispatch_queue_create("label", DISPATCH_QUEUE_SERIAL);
dispatch_sync(queue, ^{
dispatch_sync(queue, ^{
NSLog(@"");
});
});
}案例二
- (void)deadlock2 {
dispatch_queue_t queue1 = dispatch_queue_create("label", DISPATCH_QUEUE_SERIAL);
dispatch_queue_t queue2 = dispatch_queue_create("label", DISPATCH_QUEUE_SERIAL);
dispatch_sync(queue1, ^{
dispatch_sync(queue2, ^{
dispatch_sync(queue1, ^{
NSLog(@"");
});
});
});
}上面两个案例死锁的原因都是同一个串行队列的任务相互等待。 当然实际工程中遇到的死锁问题会更加复杂,难以分析。
典型误区#
在阅读相关书籍、博客都提到了一个方法dispatch_get_current_queue(),通过这个方法可以获取到当前队列,于是有人就用它来解决死锁问题。
- (void)safeSync:(void(^)())block {
if (!block) {
return;
}
if (dispatch_get_current_queue() == queue) {
block();
} else {
dispatch_sync(queue, ^{
block();
});
}
}第一眼看起来天衣无缝,对于案例一的确可以完美解决,但是对于案例二这种对队列的情况就判断不了。难怪苹果在iOS6就注释了这个方法。
推荐阅读:




