GCD常见的死锁问题之一

版权声明:本文为博主原创文章,转载请注明,谢谢! https://blog.csdn.net/qq_33646395/article/details/80254150

- (void)viewDidLoad {

    [super viewDidLoad];

    // Do any additional setup after loading the view, typically from a nib.

    

    NSLog(@"1");

    dispatch_sync(dispatch_get_main_queue(), ^{

        NSLog(@"2");

    });

    NSLog(@"3");

- (void)viewDidLoad {

    [super viewDidLoad];

    // Do any additional setup after loading the view, typically from a nib.

    

    NSLog(@"1");

    dispatch_async(dispatch_get_main_queue(), ^{

        NSLog(@"2");

    });

    NSLog(@"3");


问:打印的结果是什么?

结果:1,因为执行到这个同步线程这里就死锁了;

结果:1,3,2 ;因为dispatch_async()被放到了主队列的末尾执行,即结束了viewDidLoad 主队列中的内容才执行这个


首先,无论是同步sync还是异步async 都是调用一个block,这个block会被放到指定的队列(queue)的队尾等待执行;至于block中是并行执行还是串行执行那就和dispatch_sync中的参数指定的queue是并行还是串行有关;不同的是sync地等到block有结果了才能进行下一步操作也就是nslog(@"3");而async不需要,可以和nslog(@"3")同时执行;


同步(sync) 操作,它会阻塞当前线程并等待 Block 中的任务执行完毕,然后当前线程才会继续往下运行;

异步(async)操作,它不会阻塞当前的线程,会一起执行任务;


viewDidLoad操作是由上到下一步一步往下执行的,dispatch_sync提交一个打印任务NSLog(@”2”)到主线程关联的串行队列中,主线程关联的串行队列现在有一个viewDidLoad任务,打印任务NSLog(@”2”)排在viewDidLoad后面,队列FIFO(先进先出)的原则,打印任务NSLog(@”2”);想要得到执行必须等到viewDidLoad执行完毕后才能得到执行,但是viewDidLoad想要执行完毕必须要等打印任务NSLog(@”2”)执行完毕,所以就卡死在这了。

猜你喜欢

转载自blog.csdn.net/qq_33646395/article/details/80254150