GCD死锁及报错提示(EXC_BAD_INSTRUCTION)
学习到多线程,就一定会涉及到死锁,今天我们通过一个小Demo一起来看一下死锁的形成,以及如何如何解决。再有就是死锁的报错信息,在viewDidLoad中我们输入下列代码
- (void)viewDidLoad { [super viewDidLoad]; NSLog(@"打印1"); dispatch_sync(dispatch_get_main_queue(), ^{ NSLog(@"打印2"); }); NSLog(@"打印3"); }
运行结果如下: 可以看到EXC_BAD_INSTRUCTION的报错信息。这就是产生了死锁。同时可以看到控制台,也仅仅输出了打印1。
我们来一起分析一下这个过程。首先打印1,然后调用dispatch_sync(dispatch_get_main_queue()同步方法。GCD同步方法中需要执行打印2。于是就产生了死锁。我们一起来分析一下GCD的同步方法机制。同步方法:1,同于当前线程要做的事。做完主线程的一件事,才能再做下一件事。2,以block方法中的是事情做完为结束。
我们一起分析一下这个Demo的流程。首先打印1,然后调用sync方法。在主线程中,我需要执行sync方法。sync方法中有一个打印2的事情。也要在主线程去做。由于主线程同一时间只能做一件事。于是打印2需要等待sync方法完成再去执行。而sync同步方法的完成,需要等待block中的打印2完成。于是就形成了死锁。两个事件相互等待。
解决方案。将sync同步方法,替换成异步方法
dispatch_async(dispatch_get_main_queue(), ^{ NSLog(@"打印2"); });
再运行一次,可以看到正常输出打印1 2 3; 关于野指针的其他文章请参考: block野指针的产生: 懒加载时序,懒加载野指针: