如果你遇到了下面這樣的崩潰李剖,你可能也遇到了dispatch_once死鎖齿椅。
Thread 0 Crashed:
0 libsystem_kernel.dylib 0x00000001917718e8 __ulock_wait + 8
1 libdispatch.dylib 0x00000001916419d0 _dispatch_unfair_lock_wait + 48
2 libdispatch.dylib 0x0000000191641b6c _dispatch_gate_wait_slow + 88
3 libdispatch.dylib 0x000000019162f710 dispatch_once_f + 124
4 Demo 0x00000001004073b8 +[MyObject sharedUserInstance]
先別著急問(wèn)我怎么解決症副,在xcode中運(yùn)行一下下面的代碼,自己分析一下自然知道怎么解決了阵子。
@interface MyObject : NSObject
+ (instancetype)sharedInstance;
@end
@implementation MyObject
+ (instancetype)sharedInstance{
static id sharedInstance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedInstance = [[self alloc] init];
});
return sharedInstance;
}
- (instancetype)init{
self = [super init];
if (self) {
[NSThread sleepForTimeInterval:2];//等待2秒
dispatch_sync(dispatch_get_main_queue(), ^{
NSLog(@"永遠(yuǎn)不會(huì)打印思杯,因?yàn)樗梨i了");
});
}
return self;
}
@end
@implementation ViewController
- (IBAction)clicked:(id)sender {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[MyObject sharedInstance];
});
[MyObject sharedInstance];
}
@end
下面進(jìn)行分析:
0秒。點(diǎn)擊按鈕挠进,在global_queue中執(zhí)行dispatch_once
0.1秒色乾。main_queue阻塞,等待獲取once_token
2秒领突。global_queue結(jié)束sleep暖璧,執(zhí)行dispatch_sync,阻塞君旦,等待main_queue漆撞。至此死鎖發(fā)生。