iOS中常见的多线程方案
iOS中常见的多线程方案GCD执行方式:dispatch_sync()和dispatch_async()两种方式
dispatch_sync:在当前线程,也就是在主线程执行;
dispatch_async:在子线程执行;
GCD队列:四种
1、手动创建的并发队列(相对于全局队列)
2、手动创建的串行队列(相对于主队列)
3、主队列(系统创建的串行队列)
4、全局队列 (系统创建的并发队列)
GCD队列
GCD容易混淆的术语
GCD容易混淆的术语各种队列的执行效果
总结:只要是sync执行或者在主队列,都不会开启新线程,并且串行执行。
各种队列的执行效果
注意:当在sync函数中往当前串行队列中添加任务,会卡住当前的串行队列,造成死锁
1、sync + 主队列
执行结果:死锁,崩溃。
原因:同步执行的特点是在当前线程立即执行,主队列也是特殊的串行队列,先进先出,按顺序执行,并且在在主线程执行。任务2放到了主队列,由于viewDidLoad任务也在主队列,切在任务2的前面,则需要先执行viewDidLoad任务,所以需要等任务3执行完毕,才能执行任务2,但是要想执行viewDidLoad全部完毕,需要等任务2,执行完毕,才能执行任务3,所以任务3要等待任务2执行完,任务2要等待任务3执行完,就造成了相互等待,最终会造成死锁。
- (void)viewDidLoad {
[super viewDidLoad];
NSLog(@"执行任务1");
dispatch_queue_t queue = dispatch_get_main_queue();
dispatch_sync(queue, ^{//主线程同步步执行
NSLog(@"执行任务2");
});
NSLog(@"执行任务3");
}
2、async + 主队列
执行结果:任务1----任务3----任务2
原因:异步执行的特点是不会立即执行,异步完成任务。
- (void)viewDidLoad {
[super viewDidLoad];
NSLog(@"执行任务1");
dispatch_queue_t queue = dispatch_get_main_queue();
dispatch_async(queue, ^{ //主线程异步执行
NSLog(@"执行任务2");
});
NSLog(@"执行任务3");
}
3、sync + 全局并发队列
执行结果:任务1----任务2----任务3
原因: 任务1和任务3是在主队列中,任务2是在全局并发队列中,有两个队列,在主线程执行。所以先执行任务1,因为任务2在全局并发队列,同步执行,则需要立即执行任务2,最后再执行任务3。
- (void)viewDidLoad {
[super viewDidLoad];
NSLog(@"执行任务1");
dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
dispatch_sync(queue, ^{ //主线程的并发队列,同步执行
NSLog(@"执行任务2");
});
NSLog(@"执行任务3");
}
4、async + 全局并发队列
执行结果:任务1----任务3----任务2
原因: 任务1和任务3是在主队列中,在主线程中执行,任务2是在全局并发队列中,且异步执行,所以在子线程中执行。
- (void)viewDidLoad {
[super viewDidLoad];
NSLog(@"执行任务1");
dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
dispatch_async(queue, ^{ //子线程的并发队列,异步执行
NSLog(@"执行任务2");
});
NSLog(@"执行任务3");
}
网友评论