1、iOS中常见的多线程分类
常见方案有pthread、NSThread、GCD、NSOperation,各种方案特点如下:
*NSThread、GCD、NSOperation底层都是基于pthread实现的。
2、GCD
2.1、GCD中执行任务的函数
GCD中有两个用来执行任务的函数,dispatch_sync(同步)和dispatch_async(异步)
dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
// 同步执行
dispatch_sync(queue, ^{
NSLog(@"同步执行任务 - %@", [NSThread currentThread]);
});
// 异步执行
dispatch_async(queue, ^{
NSLog(@"异步执行任务 - %@", [NSThread currentThread]);
});
打印结果:
~: 同步执行任务 - <NSThread: 0x60000254c540>{number = 1, name = main}
~: 异步执行任务 - <NSThread: 0x600002542400>{number = 4, name = (null)}
异步会在子线程里执行任务,同步会在主线程里执行任务。
CGD也是开源的,可以参考:GCD源码。
2.1、GCD的队列
GCD的队列分为两大类型:
并发队列(Concurrent Dispatch Queue):
dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
dispatch_async(queue, ^{
for (int i = 0; i < 10; i++) {
NSLog(@"执行任务1 - %@", [NSThread currentThread]);
}
});
dispatch_async(queue, ^{
for (int i = 0; i < 10; i++) {
NSLog(@"执行任务2 - %@", [NSThread currentThread]);
}
});
打印结果:
~: 执行任务2 - <NSThread: 0x600000bbc780>{number = 6, name = (null)}
~: 执行任务1 - <NSThread: 0x600000bc5b00>{number = 3, name = (null)}
~: 执行任务1 - <NSThread: 0x600000bc5b00>{number = 3, name = (null)}
~: 执行任务2 - <NSThread: 0x600000bbc780>{number = 6, name = (null)}
~: 执行任务1 - <NSThread: 0x600000bc5b00>{number = 3, name = (null)}
~: 执行任务2 - <NSThread: 0x600000bbc780>{number = 6, name = (null)}
......
特点:可以让多个任务同时执行,会自动开启多个线程同时执行任务。并发功能只能在异步(dispatch_async)函数下才有效。
串行队列(Serial Dispatch Queue):
......
~: 执行任务1 - <NSThread: 0x60000227a380>{number = 6, name = (null)}
~: 执行任务1 - <NSThread: 0x60000227a380>{number = 6, name = (null)}
~: 执行任务1 - <NSThread: 0x60000227a380>{number = 6, name = (null)}
~: 执行任务2 - <NSThread: 0x60000227a380>{number = 6, name = (null)}
~: 执行任务2 - <NSThread: 0x60000227a380>{number = 6, name = (null)}
~: 执行任务2 - <NSThread: 0x60000227a380>{number = 6, name = (null)}
......
特点:让任务一个接着一个地执行(一个任务执行完毕后,再执行下一个任务)。
3、容易混淆的术语
3.1、同步、异步
同步和异步主要影响:能不能开启新的线程
同步:在当前线程中执行任务,不具备开启新线程的能力
异步:在新的线程中执行任务,具备开启新线程的能力
(主队列中,异步执行不能开启新线程)
3.2、并发、串行
并发:多个任务同时执行
串行:一个任务执行完毕后,再执行下一个任务
4、各种队列的执行效果
只有异步执行的并发队列才会并发(同时)执行任务,其他情况都是串行(依次)执行。
只有异步执行的并发队列和手动创建的串行队列才会开启新的线程执行任务,其他情况都不会开启新的线程(在当前线程执行)。