# 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>


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://ryukiedev.gitbook.io/wiki/ios/duo-xian-cheng/ios-duo-xian-cheng-fang-an.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
