# 04.iOS多线程方案

## 一: 总览

![](http://api.cocoachina.com/uploads/20170707/1499394732413995.png)

* pthread
  * 几乎不用
  * C语言的,全部由程序员自己管理
* NSThread
  * 程序员自己管理线程,用得少
* GCD
  * 自动管理
* NSOperation
  * 基于GCD
  * 比GCD多了一些使用功能
  * 面向对象

## 二: GCD

### 特点

* GCD会自动是用更多的CPU内核
* 自动管理线程生命周期(创建,调度,销毁等)
* 程序员只用高数GCD想要如何执行什么任务,不用编写线程管理代码

### group

* 使用 enter leave 的时候一定要出入数量对等否则会崩溃的

### dispatch\_barrier\_async

> 多个任务分两组完成

```
 // 并发队列
    dispatch_queue_t queue = dispatch_queue_create("test", DISPATCH_QUEUE_CONCURRENT);

    // 异步执行
    dispatch_async(queue, ^{
        for (int i = 0; i < 3; i++) {
            NSLog(@"栅栏：并发异步1   %@",[NSThread currentThread]);
        }
    });
    dispatch_async(queue, ^{
        for (int i = 0; i < 3; i++) {
            NSLog(@"栅栏：并发异步2   %@",[NSThread currentThread]);
        }
    });

    dispatch_barrier_async(queue, ^{
        NSLog(@"------------barrier------------%@", [NSThread currentThread]);
        NSLog(@"******* 并发异步执行，但是34一定在12后面 *********");
    });

    dispatch_async(queue, ^{
        for (int i = 0; i < 3; i++) {
            NSLog(@"栅栏：并发异步3   %@",[NSThread currentThread]);
        }
    });
    dispatch_async(queue, ^{
        for (int i = 0; i < 3; i++) {
            NSLog(@"栅栏：并发异步4   %@",[NSThread currentThread]);
        }
    });
```

### dispatch\_apply 并行遍历

> 和group关联的API,会在所有任务执行完成后执行后续操作 "完成"会在全部执行完成后打印出来

* 应用场景
  * 可在某些场景代替for循环
    * 全部遍历,无顺序要求
  * 不同文件并行iOS

```
 NSArray *array = [NSArray arrayWithObjects:@"/Users/chentao/Desktop/copy_res/gelato.ds",
                      @"/Users/chentao/Desktop/copy_res/jason.ds",
                      @"/Users/chentao/Desktop/copy_res/jikejunyi.ds",
                      @"/Users/chentao/Desktop/copy_res/molly.ds",
                      @"/Users/chentao/Desktop/copy_res/zhangdachuan.ds",
                      nil];
    NSString *copyDes = @"/Users/chentao/Desktop/copy_des";
    NSFileManager *fileManager = [NSFileManager defaultManager];
    dispatch_async(dispatch_get_global_queue(0, 0), ^(){
        dispatch_apply([array count], dispatch_get_global_queue(0, 0), ^(size_t index){
            NSLog(@"copy-%ld", index);
            NSString *sourcePath = [array objectAtIndex:index];
            NSString *desPath = [NSString stringWithFormat:@"%@/%@", copyDes, [sourcePath lastPathComponent]];
            [fileManager copyItemAtPath:sourcePath toPath:desPath error:nil];
        });
        NSLog(@"完成");
    });
```

## 三: NSOperation

> 基于GCD封装 配合NSOperationQueue实现多线程

* 使用步骤
  * 创建任务
    * 先将需要执行的操作封装到NSOperation对象中
  * 创建队列
    * 创建NSOperationQueue
  * 将任务加入队列
    * 将NSOperation加入到NSOperationQueue中
* 使用注意
  * 由于NSOperation是抽象类需要使用其子类
    * NSInvocationOperation
      * 指定Target和Selectore
    * NSBlockOperation
      * 基于Block
    * 定义继承自NSOperation的子类

### NSOperationQueue

> 暂停和取消不是立刻取消当前操作，而是等当前的操作执行完之后不再进行新的操作。

## 参考

> <http://www.cocoachina.com/articles/19769>
