iOS 多线程简单使用的具体解释

主线程

  • 一个iOS程序执行后。默认会开启1条线程,称为“主线程”或“UI线程”(刷新UI界面最好在主线程中做。在子线程中可能会出现莫名其妙的BUG)
  • 主线程的作用 
    • 显示刷新UI界面
    • 处理UI事件(比方点击事件、滚动事件、拖拽事件等)
  • 注意点 
    • 别将比較耗时的操作放到主线程中
    • 耗时操作会卡住主线程,严重影响UI的流畅度,给用户一种“卡”的坏体验
  • iOS中多线程的实现方案 
    • pthread(c语言。程序猿管理) 
      • 一套通用的多线程API
      • 适用于UnixLinuxWindows等系统
      • 跨平台可移植
      • 使用难度大
    • NSThread(oc语言,程序猿管理) 
      • 使用更加面向对象
      • 简单易用。可直接操作线程对象
    • GCD(c语言,自己主动管理) 
      • 旨在替代NSThread等线程技术
      • 充分利用设备的多核
    • NSOperation(oc语言,自己主动管理) 
      • 基于GCD(底层是GCD)
      • 比GCD多了一些更简单有用的功能
      • 使用更加面向对象

NSThread

  • 一个NSThread对象就代表一条线程
  • 创建、启动线程
<code class="hljs objectivec has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;"><span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">NSThread</span> *thread = [[<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">NSThread</span> alloc] initWithTarget:<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">self</span> selector:<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">@selector</span>(run) object:<span class="hljs-literal" style="color: rgb(0, 102, 102); box-sizing: border-box;">nil</span>];
[thread start];
<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 线程一启动。就会在线程thread中运行self的run方法</span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute;  50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right- 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute;  50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right- 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li></ul>
  • 常见相关使用方法
<code class="hljs objectivec has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;">+ (<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">NSThread</span> *)mainThread; <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 获得主线程</span>
- (<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">BOOL</span>)isMainThread; <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 是否为主线程</span>
+ (<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">BOOL</span>)isMainThread; <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 是否为主线程</span>

<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 获取当前线程</span>
<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">NSThread</span> *current = [<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">NSThread</span> currentThread];

<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 线程的名字</span>
- (<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span>)setName:(<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">NSString</span> *)n;
- (<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">NSString</span> *)name;</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute;  50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right- 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute;  50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right- 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li></ul>
  • 其它创建线程方式 
    • 长处:简单快捷
    • 缺点:无法对线程进行更具体的设置
<code class="hljs objectivec has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;"><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 创建线程后自己主动启动线程</span>
[<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">NSThread</span> detachNewThreadSelector:<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">@selector</span>(run) toTarget:<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">self</span> withObject:<span class="hljs-literal" style="color: rgb(0, 102, 102); box-sizing: border-box;">nil</span>];

<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 隐式创建并启动线程</span>
[<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">self</span> performSelectorInBackground:<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">@selector</span>(run) withObject:<span class="hljs-literal" style="color: rgb(0, 102, 102); box-sizing: border-box;">nil</span>];</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute;  50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right- 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute;  50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right- 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li></ul>
  • 控制线程的状态
<code class="hljs objectivec has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;"><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 启动线程</span>
- (<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span>)start; 
<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 进入就绪状态 -> 执行状态。当线程任务执行完成,自己主动进入死亡状态</span>

<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 堵塞(暂停)线程</span>
+ (<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span>)sleepUntilDate:(<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">NSDate</span> *)date;
+ (<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span>)sleepForTimeInterval:(<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">NSTimeInterval</span>)ti;
<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 进入堵塞状态</span>

<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 强制停止线程</span>
+ (<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span>)exit;
<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 进入死亡状态</span>
<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 注意:一旦线程停止(死亡)了,就不能再次开启任务</span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute;  50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right- 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute;  50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right- 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li></ul>

相互排斥锁

  • 相互排斥锁使用格式
<code class="hljs scss has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;"><span class="hljs-at_rule" style="box-sizing: border-box;">@<span class="hljs-function" style="box-sizing: border-box;">synchronized(锁对象)</span> {</span> <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 须要锁定的代码  }</span>
<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 注意:锁定1份代码仅仅用1把锁。用多把锁是无效的</span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute;  50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right- 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute;  50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right- 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li></ul>

原子和非原子属性

  • OC在定义属性时有nonatomic和atomic两种选择 
    • atomic:原子属性,为setter方法加锁(默认就是atomic)
    • nonatomic:非原子属性。不会为setter方法加锁
  • nonatomic和atomic对照 
    • atomic:线程安全,须要消耗大量的资源
    • nonatomic:非线程安全。适合内存小的移动设备
  • iOS开发的建议 
    • 全部属性都声明为nonatomic
    • 尽量避免多线程抢夺同一块资源
    • 尽量将加锁、资源抢夺的业务逻辑交给server端处理,减小移动client的压力

线程间的通信

  • 什么叫做线程间通信 
    • 在1个进程中。线程往往不是孤立存在的。多个线程之间须要常常进行通信
  • 线程间通信的体现 
    • 1个线程传递数据给另1个线程
    • 在1个线程中运行完特定任务后,转到另1个线程继续运行任务
  • 线程间通信经常用法
<code class="hljs erlang has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;"><span class="hljs-pp" style="box-sizing: border-box;">- <span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(void)</span>performSelectorOnMainThread:<span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(<span class="hljs-variable" style="box-sizing: border-box;">SEL</span>)</span>aSelector withObject:<span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(id)</span>arg waitUntilDone:<span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(<span class="hljs-variable" style="box-sizing: border-box;">BOOL</span>)</span>wait;

- <span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(void)</span>performSelector:<span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(<span class="hljs-variable" style="box-sizing: border-box;">SEL</span>)</span>aSelector onThread:<span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(<span class="hljs-variable" style="box-sizing: border-box;">NSThread</span> *)</span>thr withObject:<span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(id)</span>arg waitUntilDone:<span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(<span class="hljs-variable" style="box-sizing: border-box;">BOOL</span>)</span>wait;</span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute;  50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right- 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute;  50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right- 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li></ul>

GCD

  • 本质及长处 
    • 全称是Grand Central Dispatch,可译为“牛逼的中枢调度器”
    • GCD会自己主动管理线程的生命周期(创建线程、调度任务、销毁线程)
    • 程序猿仅仅须要告诉GCD想要运行什么任务,不须要编写不论什么线程管理代码
  • 使用GCD的步骤 
    • 定制任务 
      • 确定想做的事情
    • 将任务加入到队列中 
      • GCD会自己主动将队列中的任务取出,放到相应的线程中运行
      • 任务的取出遵循队列的FIFO原则:先进先出,后进后出
  • 运行任务经常使用的函数
<code class="hljs objectivec has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;"><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 用同步的方式运行任务</span>
<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">dispatch_sync</span>(<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">dispatch_queue_t</span> queue, dispatch_block_t block);
<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// queue:队列</span>
<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// block:任务</span>
<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 注意:使用sync函数往当前串行队列中加入任务,会卡住当前的串行队列。同步方式会堵塞当前队列。

</span> <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 用异步的方式运行任务</span> <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">dispatch_async</span>(<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">dispatch_queue_t</span> queue, dispatch_block_t block); dispatch_barrier_async(<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">dispatch_queue_t</span> queue, dispatch_block_t block); <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 在前面的任务运行结束后它才运行。并且它后面的任务等它运行完毕之后才会运行</span> <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 注意:这个queue不能是全局的并发队列</span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right- 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right- 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li></ul>

  • 同步和异步的差别 
    • 同步:仅仅能在当前线程中运行任务。不具备开启新线程的能力
    • 异步:能够在新的线程中运行任务,具备开启新线程的能力
  • 队列的类型 
    • 并发队列(Concurrent Dispatch Queue) 
      • 能够让多个任务并发(同一时候)运行(自己主动开启多个线程同一时候运行任务)
      • 并发功能仅仅有在异步(dispatch_async)函数下才有效
    • 串行队列(Serial Dispatch Queue) 
      • 让任务一个接着一个地运行(一个任务运行完成后,再运行下一个任务)
  • 并发队列
<code class="hljs lasso has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;"><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 创建并发队列</span>
dispatch_queue_t <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">queue</span> <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">=</span> dispatch_queue_create(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"队列名称"</span>, DISPATCH_QUEUE_CONCURRENT)
<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 第一个參数 const char *label 队列名称 </span>
<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 第二个參数 dispatch_queue_attr_t attr 队列的类型 DISPATCH_QUEUE_CONCURRENT 表示并发队列</span>

<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 获得全局的并发队列</span>
dispatch_queue_t <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">queue</span> <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">=</span> dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>); 
<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 第一个參数 dispatch_queue_priority_t priority 队列的优先级</span>
<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 第二个參数 unsigned long flags 此參数临时无用,用0就可以</span>
<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">#define</span> DISPATCH_QUEUE_PRIORITY_HIGH <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">2</span> <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 高</span>
<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">#define</span> DISPATCH_QUEUE_PRIORITY_DEFAULT <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span> <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 默认(中)</span>
<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">#define</span> DISPATCH_QUEUE_PRIORITY_LOW (<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">-</span><span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">2</span>) <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 低</span>
<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">#define</span> DISPATCH_QUEUE_PRIORITY_BACKGROUND INT16_MIN <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 后台</span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute;  50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right- 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute;  50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right- 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li></ul>
  • 串行队列
<code class="hljs objectivec has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;"><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 创建串行队列(队列类型传递NULL或者DISPATCH_QUEUE_SERIAL)</span>
<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">dispatch_queue_t</span> queue = dispatch_queue_create(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"队列名称"</span>, <span class="hljs-literal" style="color: rgb(0, 102, 102); box-sizing: border-box;">NULL</span>); 
<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 获得主队列。主队列也是串行队列</span>
<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">dispatch_queue_t</span> queue = dispatch_get_main_queue();</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute;  50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right- 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute;  50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right- 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li></ul>
  • 线程间的通信
<code class="hljs r has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;">// 从子线程回到主线程
dispatch_async(
dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>), ^{
    // 运行耗时的异步操作<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">...</span>
      dispatch_async(dispatch_get_main_queue(), ^{
        // 回到主线程,运行UI刷新操作
        });
});</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute;  50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right- 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute;  50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right- 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li></ul>
  • 延迟操作 
    • iOS中延迟操作有3种 
      • 调用NSObject的方法
      • 使用GCD函数
      • 使用NSTimer
<code class="hljs r has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;">[self performSelector:@selector(run) withObject:nil afterDelay:<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">2.0</span>];
// <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">2</span>秒后再调用self的run方法

dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">2.0</span> * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
    // <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">2</span>秒后运行这里的代码<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">...</span>
});

[NSTimer scheduledTimerWithTimeInterval:<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">2.0</span> target:self selector:@selector(test) userInfo:nil repeats:NO];</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute;  50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right- 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute;  50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right- 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li></ul>
  • 一次性代码
<code class="hljs objectivec has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;"><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 使用dispatch_once函数能保证某段代码在程序运行过程中仅仅被运行1次</span>
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">static</span> <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">dispatch_once_t</span> onceToken;
<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">dispatch_once</span>(&onceToken, ^{
    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 仅仅运行1次的代码(这里面默认是线程安全的)</span>
});</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute;  50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right- 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute;  50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right- 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li></ul>
  • 高速迭代
<code class="hljs scss has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;"><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 使用dispatch_apply函数能进行高速迭代遍历</span>
<span class="hljs-function" style="box-sizing: border-box;">dispatch_apply(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">10</span>, <span class="hljs-function" style="box-sizing: border-box;">dispatch_get_global_queue(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>)</span>, ^(size_t index)</span>{
    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 运行10次代码,index顺序不确定</span>
});</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute;  50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right- 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute;  50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right- 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li></ul>
  • 队列组 
    • 能够满足的一种需求(当然也能够用依赖线程依赖实现,下文会提到) 
      • 首先:分别异步运行2个耗时的操作
      • 其次:等2个异步操作都运行完成后,再回到主线程运行操作
<code class="hljs r has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;">dispatch_group_t group =  dispatch_group_create();
dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>), ^{
    // 运行<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>个耗时的异步操作
});
dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>), ^{
    // 运行<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>个耗时的异步操作
});
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
    // 等前面的异步操作都运行完成后,回到主线程<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">...</span>
});</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute;  50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right- 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute;  50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right- 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li></ul>

单例模式

  • 单例模式的作用 
    • 能够保证在程序执行过程,一个类仅仅有一个实例,并且该实例易于供外界訪问
    • 从而方便地控制了实例个数,并节约系统资源
  • 单例模式的使用场合 
    • 在整个应用程序中,共享一份资源(这份资源仅仅须要创建初始化1次)
  • 实现步骤:
<code class="hljs objectivec has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;"><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 在.m中保留一个全局的static的实例</span>
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">static</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">id</span> _instance;

<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 重写allocWithZone:方法,在这里创建唯一的实例(注意线程安全),alloc方法会调用allocWithZone:方法</span>
+ (instancetype)allocWithZone:(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">struct</span> _NSZone *)zone
{
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">static</span> <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">dispatch_once_t</span> onceToken;
    <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">dispatch_once</span>(&onceToken, ^{
        _instance = [<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">super</span> allocWithZone:zone];
    });
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> _instance;
}
<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 提供1个类方法让外界訪问唯一的实例</span>
+ (instancetype)sharedInstance
{
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">static</span> <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">dispatch_once_t</span> onceToken;
    <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">dispatch_once</span>(&onceToken, ^{
        _instance = [[<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">self</span> alloc] init];
    });
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> _instance;
}
<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 实现copyWithZone:方法</span>
- (<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">id</span>)copyWithZone:(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">struct</span> _NSZone *)zone
{
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> _instance;
}</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute;  50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right- 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute;  50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right- 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li></ul>

NSOperation

  • NSOperation和NSOperationQueue实现多线程的详细步骤 
    • 先将须要运行的操作封装到一个NSOperation对象中
    • 然后将NSOperation对象加入到NSOperationQueue中
    • 系统会自己主动将NSOperationQueue中的NSOperation取出来
    • 将取出的NSOperation封装的操作放到一条新线程中运行
  • NSOperation是抽象类,使用NSOperation子类的方式有3种 
    • NSInvocationOperation
    • NSBlockOperation
    • 自己定义子类继承NSOperation,实现内部对应的方法
  • NSInvocationOperation
<code class="hljs objectivec has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;"><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 创建NSInvocationOperation对象</span>
- (<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">id</span>)initWithTarget:(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">id</span>)target selector:(SEL)sel object:(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">id</span>)arg;

<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 调用start方法開始运行操作</span>
- (<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span>)start;
<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 一旦运行操作,就会调用target的sel方法</span>
<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 注意:默认情况下,调用了start方法后并不会开一条新线程去运行操作。而是在当前线程同步运行操作。仅仅有将NSOperation放到一个NSOperationQueue中,才会异步运行操作</span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute;  50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right- 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute;  50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right- 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li></ul>
  • NSBlockOperation
<code class="hljs objectivec has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;"><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 创建NSBlockOperation对象</span>
+ (<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">id</span>)blockOperationWithBlock:(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> (^)(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span>))block;

<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 通过addExecutionBlock:方法加入很多其它的操作</span>
- (<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span>)addExecutionBlock:(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> (^)(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span>))block;

<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 注意:仅仅要NSBlockOperation封装的操作数 > 1。就会异步运行操作</span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute;  50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right- 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute;  50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right- 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li></ul>
  • NSOperationQueue
<code class="hljs erlang has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;">// 加入操作到<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">NSOperationQueue</span>中
<span class="hljs-pp" style="box-sizing: border-box;">- <span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(void)</span>addOperation:<span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(<span class="hljs-variable" style="box-sizing: border-box;">NSOperation</span> *)</span>op;
- <span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(void)</span>addOperationWithBlock:<span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(void (^)</span><span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(void)</span>)block;</span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute;  50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right- 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute;  50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right- 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li></ul>
  • 相关操作
<code class="hljs objectivec has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;"><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 设置最大并发数</span>
- (<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">NSInteger</span>)maxConcurrentOperationCount;
- (<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span>)setMaxConcurrentOperationCount:(<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">NSInteger</span>)cnt;

<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 取消队列的全部操作</span>
- (<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span>)cancelAllOperations;
<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 提示:也能够调用NSOperation的- (void)cancel方法取消单个操作</span>

<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 暂停和恢复队列</span>
- (<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span>)setSuspended:(<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">BOOL</span>)b; <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// YES代表暂停队列。NO代表恢复队列</span>
- (<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">BOOL</span>)isSuspended;</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute;  50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right- 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute;  50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right- 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li></ul>
  • 操作依赖 
    • NSOperation之间能够设置依赖来保证运行顺序
    • 能够在不同queue的NSOperation之间创建依赖关系
<code class="hljs ini has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;"><span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 102, 102);">[operationB addDependency:operationA]</span><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">; // 操作B依赖于操作A</span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute;  50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right- 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute;  50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right- 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li></ul>
  • 操作的监听
<code class="hljs cs has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;"><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 能够监听一个操作的运行完成</span>
- (<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> (^)(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span>))completionBlock;
- (<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span>)setCompletionBlock:(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> (^)(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span>))block;</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute;  50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right- 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute;  50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right- 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li></ul>
  • 自己定义NSOperation 
    • 仅仅须要重写- (void)main方法。在里面实现想运行的任务
    • 注意点 
      • 自己创建自己主动释放池(由于假设是异步操作,无法訪问主线程的自己主动释放池)
      • 常常通过- (BOOL)isCancelled方法检測操作是否被取消,对取消做出响应

计算时间差

<code class="hljs sql has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;">NSDate *<span class="hljs-operator" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">start</span> = [NSDate <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">date</span>];</span>
// 上下两句代码间放须要计算时间的程序
NSDate *<span class="hljs-operator" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">end</span> = [NSDate <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">date</span>];</span>
NSLog(@"%f", [<span class="hljs-operator" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">end</span> timeIntervalSinceDate:<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">start</span>]);</span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute;  50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right- 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute;  50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right- 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li></ul>
<code class="hljs sql has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;">CFTimeInterval <span class="hljs-operator" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">begin</span> = CFAbsoluteTimeGetCurrent();</span>
// 上下两句代码间放须要计算时间的程序
CFTimeInterval <span class="hljs-operator" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">end</span> = CFAbsoluteTimeGetCurrent();</span>
NSLog(@"%f", <span class="hljs-operator" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">end</span> - <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">begin</span>);</span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute;  50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right- 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute;  50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right- 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li></ul>

小结:

1、在GCD中,方法假设用异步函数能够开启子线程做事情。该方法中的程序会顺序运行究竟,然后再返回去开启子线程运行内部的操作。假设是同步函数。则不能开启子线程,里面的同步函数仅仅能一个一个运行下去。 
2、假设在主队列中调用同步函数,easy造成死锁。

0
原文地址:https://www.cnblogs.com/wzzkaifa/p/7396446.html