下面这个程序会打印出什么结果:1
2
3
4
5
6
7-(void)syncDemo{
NSLog(@"打印1");
dispatch_sync(dispatch_get_main_queue(), ^{
NSLog(@"打印2");
});
NSLog(@"打印3");
}
结果是:1
22017-03-24 15:49:05.878072+0800 textDemo[726:286339] 打印1
(lldb)
并且有EXC_BAD_INSTRUCTION的报错信息1
Thread 1: EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0)
我们来一起分析一下这个过程。首先打印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同步方法,替换成异步方法1
2
3dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"打印2");
});
这样就可以看到正常打印了:1
2
32017-03-24 16:34:20.208022+0800 textDemo[19419:343315] 打印1
2017-03-24 16:34:20.208206+0800 textDemo[19419:343315] 打印3
2017-03-24 16:34:20.211819+0800 textDemo[19419:343315] 打印2