在iOS开发中多线程技术常用的就是GCD和NSOperation,以下介绍这两种的基本使用.
GCD:
GCD的基本概念
同步函数 sync (不管是串行队列还是并行队列还是主队列,都不会开启新线程)
异步函数 async (串行队列和并行队列下会开启新线程)
GCD会自动的去控制线程的生命周期
GCD的基本使用
1.同步函数下添加串行队列
dispatch_queue_t queue = dispatch_queue_create("自定义串行队列名称", NULL); 获得串行队列
dispatch_sync(queue, ^{ 添加任务到队列中执行
任务代码
});
总结: 不会开启新的线程
2.同步函数下添加并行队列
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); 获得全局并发队列
dispatch_sync(queue, ^{ 添加任务到队列中 执行
任务代码
});
总结:不会开启新的线程, 并发队列失去了并发的功能
3.同步函数下添加主队列
dispatch_queue_t queue = dispatch_get_main_queue(); 获得主队列
dispatch_sync(queue, ^{ 添加任务到队列中 执行
任务代码
});
总结:不会开启新的线程,所有任务在主线程中执行
4.异步函数下添加串行队列
dispatch_queue_t queue = dispatch_queue_create("自定义串行队列名", NULL); 获得串行队列
dispatch_async(queue, ^{ 添加任务到队列中 执行
任务代码
});
总结: 只开1个线程执行任务
5.异步函数下添加并行队列
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); 获得并行队列
dispatch_async(queue, ^{ 添加任务到队列中 执行
任务代码
});
总结: 可开多个线程
6.异步函数下添加主队列
dispatch_queue_t queue = dispatch_get_main_queue(); 获得主队列
dispatch_async(queue, ^{ 添加任务到队列中 执行
任务代码
});
总结: 不会开启新线程
7.从子线程回到主线程
dispatch_async(
dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
执行异步操作...
dispatch_async(dispatch_get_main_queue(), ^{
回到主线程,执行UI刷新操作
});
});
8.GCD延时操作(会开启新线程)
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
2秒后异步执行这里的代码...
});
9.只执行一次(例如可用于单例模式)
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
只执行1次的代码(这里面默认是线程安全的)
});
10.队列组的使用
dispatch_group_t group = dispatch_group_create();
dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
执行1个异步操作
});
dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
执行1个异步操作
});
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
等前面的异步操作都执行完毕后,回到主线程...
});
两种创建方式
1,NSInvocationOperation *operation1 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(方法名) object:nil];
2,NSBlockOperation *operation2 = [NSBlockOperation blockOperationWithBlock:^{
代码段
}];
2.1通过block创建可以在operation2中直接添加代码段,新添加的代码段是存在于operation2内部的
[operation3 addExecutionBlock:^{
代码段
}];
[operation start];调用此方法立即执行任务代码,但是是同步执行(不会开启新线程)
但,只要NSBlockOperation封装的任务代码 > 1,就会异步执行操作,自动开启新线程
3,创建队列才会异步执行(开启新线程) NSOperationQueue *queue = [[NSOperationQueue alloc] init];
4,设置最大线程数
queue.maxConcurrentOperationCount = 2; // 2 ~ 3为宜
5,启动队列
添加操作到队列中(自动执行操作,自动开启线程)
[queue addOperation:operation1];
[queue addOperation:operation2];
或者直接添加block代码到队列中
[queue addOperationWithBlock:^{
任务代码
}];
5,设置依赖设置2为1的依赖,则必须等待1执行完毕后才会执行2
[operation2 addDependency:operation1];
6,暂停队列恢复队列 YES代表暂停队列,NO代表恢复队列
[queue setSuspended:YES];
- (BOOL)isSuspended;
7,取消队列操作
取消队列所有操作
[queue cancelAllOperations];
取消队列某个操作
[operation1 cancel];