> For the complete documentation index, see [llms.txt](https://philm.gitbook.io/philm-ios-wiki/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://philm.gitbook.io/philm-ios-wiki/mei-zhou-yue-du/30-hang-dai-ma-yan-shi-dispatchonce-si-suo.md).

# 30行代码演示dispatch\_once死锁

如果你遇到了下面这样的崩溃，你可能也遇到了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]
```

先别着急问我怎么解决，在xcode中运行一下下面的代码，自己分析一下自然知道怎么解决了。

```
30行代码演示dispatch_once死锁
96  giveme5 关注
2017.05.31 20:25* 字数 143 阅读 45评论 0喜欢 0
如果你遇到了下面这样的崩溃，你可能也遇到了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] 
先别着急问我怎么解决，在xcode中运行一下下面的代码，自己分析一下自然知道怎么解决了。

@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(@"永远不会打印，因为死锁了");
        });
    }
    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
```

下面进行分析：

0秒。点击按钮，在global\_queue中执行dispatch\_once 0.1秒。main\_queue阻塞，等待获取once\_token 2秒。global\_queue结束sleep，执行dispatch\_sync，阻塞，等待main\_queue。至此死锁发生。

参考：

[Dispatch\_once造成的死锁—-分析、解决与自动检测](http://openfibers.github.io/blog/2016/10/22/deadlock-caused-by-dispatch-once/)
