GCD死锁及报错提示(EXC_BAD_INSTRUCTION)

本文探讨了多线程中的死锁问题,通过一个iOS GCD同步方法导致的死锁示例进行分析。在viewDidLoad中使用dispatch_sync引发死锁,报错信息为EXC_BAD_INSTRUCTION。解释了同步方法的工作原理,指出主线程因等待同步任务完成(打印2)而被阻塞,而同步任务又依赖主线程执行,从而形成死锁。解决方法是将sync替换为异步方法。最后提供了相关野指针问题的文章链接。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

学习到多线程,就一定会涉及到死锁,今天我们通过一个小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野指针的产生:
http://blog.youkuaiyun.com/lee727n/article/details/76594408
懒加载时序,懒加载野指针:
http://blog.youkuaiyun.com/lee727n/article/details/75090292

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值