#iOS多线程学习&总结
在查阅资料文档,系统得重新审视了下iOS多线程。下面是自己结合资料做的一些整理,比较偏基础。
后续还会有一篇关于线程间通信的整理
##基本概念
- 进程:一个具有一定独立功能的程序关于某个数据集合的一次运动活动。可以理解成一个运行中的应用程序。
- 线程:程序执行流的最小单元,线程是进程中的一个实体。
- 同步:只能在当前线程按先后顺序依次执行,不开启新线程。
- 异步:可以在当前线程开启多个新线程执行,可以不按顺序执行。
- 队列: 装载线程任务的队形结构。
- 并发:线程执行可以同时一起执行。
- 串行:线程执行只能依次逐一先后有序的执行。
##iOS多线程对比
###NSThread
每个NSThread对象对应一个线程,真正最原始的线程。
- 优点:NSThread 轻量级,相对使用简单。
- 缺点:需要手动管理线程活动,控制生命周期、线程加锁、睡眠、唤醒等。
###NSOperation
- 优点:不需要关心线程管理,重心可以放在执行逻辑上。
- 缺点:面向对象的线程技术,只能使用NSOperation的两个子类。
1. NSInvocationOperation:实例方法创建线程。
2. NSBlockOperation:类方法创建线程,在Block里是事件内容。
###GCD
多核编程、对底层C语言的封装,苹果推荐使用。
- 优点:最高效,避开并发陷阱。
- 缺点:基于C实现。
##多线程如何使用
###NSThread
####三种实现开启线程方式:
- 动态实例化
```
NSThread *thread = [[NSThread alloc] initWithTarget:self
selector:@selector(loadImg:)
object:imgUrl];
thread.threadPriority = 1;
[thread start];
```
- 静态实例化
```
[NSThread detachNewThreadSelector:@selector(loadImg:)
toTarget:self
withObject:imgUrl];
```
- 隐式实例化
```
[self performSelectorInBackground:@selector(loadImg:)
withObject:imgUrl];
```
###NSOperation
主要的实现方式:结合NSOperation和NSOperationQueue实现多线程编程。
- 实例化NSOperation的子类,绑定执行的操作。
- 创建NSOperationQueue队列,将NSOperation实例添加进来。
- 系统会自动将NSOperationQueue队列中检测取出和执行NSOperation的操作。
####使用NSOperation的子类实现创作线程
- NSInvocationOperation创建线程
```
NSInvocationOperation *invocationOperation = [[NSInvocationOperation alloc]
initWithTarget:self
selector:@selector(loadImg:)
object:imgUrl];
NSOperationQueue *queue = [[NSOperationQueue alloc]init];
[queue addOperation:invocationOperation];
```
- NSBlockOperation创建线程
```
NSBlockOperation *blockOperation = [NSBlockOperation blockOperationWithBlock:^{
[self loadImageSource:imgUrl];
}];
NSOperationQueue *queue = [[NSOperationQueue alloc]init];
[queue addOperation:blockOperation];
```
###GCD
高性能的多线程解决方案。
- 主线程队列(刷新UI)
`dispatch_get_main_queue()`
- 并行队列
`dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)`
```
DISPATCH_QUEUE_PRIORITY_DEFAULT:默认优先级
DISPATCH_QUEUE_PRIORITY_HIGH:高优先级
DISPATCH_QUEUE_PRIORITY_LOW:低优先级
```
- 串行队列
`dispatch_queue_create("queue_name", NULL)`
####GCD多线程实现(六种)
- 主线程执行
```
dispatch_async(dispatch_get_main_queue(), ^{
[self loadImg:imgUrl];
});
```
- 后台执行线程
```
dispatch_async(dispatch_get_global_queue(0, 0), ^{
[self loadImg:imgUrl];
});
```
- 延迟执行
```
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW,TIME * NSEC_PER_SEC);
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
[self loadImg:imgUrl];
});
```
- 一次性执行(可用来写单例)
```
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
[self loadImg:imgUrl];
});
```
- 并发执行循环迭代
```
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
size_t count = number;
dispatch_apply(count, queue, ^(size_t i) {
[self loadImg:imgUrl];
});
```
- 自定义队列
```
dispatch_queue_t customQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_async(customQueue, ^{
[self loadImg:imgUrl];
});
```