[iOS]主线程同步派发一个block任务死锁问题

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    
    dispatch_queue_t mainQueue = dispatch_get_main_queue();
//    dispatch_sync(mainQueue, ^{
//        //代码无法执行
//        NSLog(@"在主线程中同步执行block任务形成死锁");
//    });
    //改成async避免死锁
    dispatch_async(mainQueue, ^{
            //代码无法执行
            NSLog(@"在主线程中异步执行block任务不形成死锁");
    });
}

死锁的原因:

主队列是串行队列,执行同步派发(dispatch_sync)时将等待其派发的block任务执行完毕后再返回,即不是立即返回,阻塞在此。
而block任务由于处在串行队列中,需要等前面派发的代码执行完毕才能执行,形成死锁。

解决办法:

不要同步派发,采用异步派发dispatch_async(派发完立即返回),则不形成死锁.

参考官方文档dispatch_sync

Submits a block to a dispatch queue for synchronous execution. Unlike dispatch_async, this function does not return until the block has finished.
这个函数直到派发的block执行完毕才返回,因此在当前队列调用会导致死锁。
Calling this function and targeting the current queue results in deadlock.

Unlike with dispatch_async, no retain is performed on the target queue. Because calls to this function are synchronous, it “borrows” the reference of the caller. Moreover, no Block_copy is performed on the block.
#####block不会自动复制到堆上,与dispatch_async不一样。

As an optimization, this function invokes the block on the current thread when possible.

Tip:百度如何搜索苹果开发者文档API参考?

以搜索苹果官方网站的dispatch_sync的参考为例,输入以下内容:

dispatch_sync site:apple.com

猜你喜欢

转载自blog.csdn.net/annkie/article/details/82782123