iOS GCD主队列中添加同步任务卡死 dispatch_get

2020-08-04  本文已影响0人  低音区

关于这个问题,查了很多资料。总是没有找到满意的答案。总是云里雾里的,在讲一些概念级别的术语。设置很多约束的情况下,推理出答案。不是很满意。自己总结了一下,猜想了一个比较认可的答案。

问题描述:
使用GCD,给主队列添加同步任务。会引起崩溃。

参考资料:iOS中主队列的同/异步执行

//声明全局队列。
@property (nonatomic, strong)dispatch_queue_t queue;

//调用全局队列,添加同步任务。
- (void)viewDidLoad {
    [super viewDidLoad];
    dispatch_sync(self.queue, ^{
        [self testMainThreadAndSync];
        NSLog(@"同步队列+并发任务");
    });
}

//任务未完成之前,再次添加同步任务。
- (void)testMainThreadAndSync{
    dispatch_sync(self.queue, ^{//报错Thread 1: EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0)
        [self syncFunction];
        NSLog(@"同步队列+并发任务");
        NSLog(@"当前线程:%@",[NSThread currentThread]);
    });
}
//定义一个方法
- (void)syncFunction{
    NSLog(@"同步方法");
}
//队列初始化方法。
- (dispatch_queue_t)queue{
    if(!_queue){
        _queue = dispatch_queue_create("like.mainQueue", DISPATCH_QUEUE_SERIAL);
    }
    return _queue;
}

思路:
创建串行队列,在同步任务 testMainThreadAndSync 执行过程中,添加同步任务 syncFunction。导致程序崩溃
得出结论:
串行队列在同步任务执行中的时候,添加新的同步任务,会导致两个任务相互等待。导致线程卡死。
主队列也是一个特殊的串行队列,由此我得出的答案是,每一个在主队列中调用的方法,都会被当做同步任务处理。而这个时候,我们的同步任务添加操作,又在主队列的同步任务中完成。导致线程卡死。

图示:

任务等待导致线程卡死

OK~ 这就是我得出的答案。

上一篇下一篇

猜你喜欢

热点阅读