苹果ios 多线程实际应用怎么开 iosios 多线程实际应用开启教程分享

在iOS开发中苹果提供了三种ios 多线程实际应用技术,分别是:

简单介绍一下GCD的使用

GCD全称 Grand Central Dispatch,可以称之为大中央调度实际上GCD是管理着一个线程池,如何创建线程如何回收線程,以及分配多少个线程这些都是GCD来控制的。在开发中程序员是不用操作线程的相关事情,程序员只需要把应该做的操作放到相应嘚队列里面即可

GCD中有多种队列,其中自定义的队列有两种:串行队列和并行队列

1:串行队列:队列中的任务只会顺序执行且一次只能夠执行一个任务。也就是说执行完一个任务后,才会执行下一个任务

2:并行队列:可以一次执行多个任务。比如说并行队列中有10个任務可以一次执行3个任务,这三个任务哪个先执行完了再接着执行剩下的任务。

注意:无论是串行队列还是并行队列他们都是FIFO(先进先出)的。也就是说无论是哪种队列,任务进队列的时间越早其执行的时间就越早(只不过某些情况下任务执行的结束时间是不确定嘚)。

GCD中有两种操作分别是同步操作和异步操作

1:同步操作:不会新开线程

2:异步操作:会开启新的线程

两种操作和两种队列,组合为4種情况实际上,在开发中有些组合基本上是不会用到的。下面用程序描述一下四种组合

组合一:串行队列+同步操作(不会新建线程,而且任务是一个一个的执行因此实际上就是顺序执行),代码如下:

//串行队列+同步操作

number = 1,说明是主线程没有新开线程。

组合二:串行隊列+异步操作(因为任务要一个一个的执行但是因为是异步操作,所以会开启一个新的线程所有的任务都在新的线程上执行),代码洳下:

//串行队列+异步操作

number = 2说明开启了一个新的子线程,但仍然是顺序执行

组合三:并行队列+同步操作(因为同步操作不会开启新的线程,因此即使并行队列可以一次开始多个任务,但实际上仍旧是每个任务都在主线程上执行且按顺序执行)。代码如下:

//并行队列+同步任务

没有开启新的线程且按顺序执行。

组合四:并行队列+异步操作(并行队列会一次开始多个任务且异步操作可以开启新的线程,洇此同一时刻可能会同时执行多个任务开启多个线程,且每个任务的结束时间是不确定的)代码如下:

//并行队列+异步任务

可以看到,開启了多个线程且任务不是按顺序执行完的。

为了方便开发苹果还提供了有全局队列,全局队列实际上是并行队列因此,全局队列嘚执行结果和并行队列的执行结果是一致的代码如下:

//全局队列+同步任务
//全局队列+异步任务

苹果还提供了一种队列是主队列,主队列是串行队列但是和串行队列又有差异。主队列上的任务都应该在主线程上顺序执行没有异步的概念。也就是说即使是异步任务在主队列上执行,也不会开启新的线程

可以看到,没有开启新的线程且是顺序执行。

主队列+同步任务(会阻塞线程)代码如下:

//主队列+同步任务,会阻塞

主队列中本身是有一个任务A的(主任务)且该任务A还没有执行完。在执行任务A的过程中又插入了新的同步任务B。我们知道串行队列中,必须先执行完一个任务后才能继续执行另一个任务。此时的情况时:

若想继续执行任务A需要先把任务B执行完,若想继续执行任务B需要先把任务A执行完,因此造成了阻塞

在开发中,应该避免这种阻塞的情况

}

主队列:是和主线程相关联的队列主队列是GCD自带的一种特殊的串行队列,放在主队列中得任务都会放到主线程中执行。
提示:如果把任务放到主队列中进行处理那麼不论处理函数是异步的还是同步的都不会开启新的线程。

(1)使用异步函数执行主队列中得任务代码示例:

打印查看(同时开启了两個子线程,分别下载图片):

首先:分别异步执行2个耗时的操作

其次:等2个异步操作都执行完毕后再回到主线程执行操作

如果想要快速高效地实现上述需求,可以考虑用队列组

}

什么是GCD呢我们先来看看百喥百科的解释简单了解下概念

Grand Central Dispatch (GCD) 是Apple开发的一个多核的较新的解决方法。它主要用于优化应用程序以支持多核处理器以及其他对称多处理它昰一个在线程池模式的基础上执行的并行任务。在Mac OS X 10.6雪豹中首次推出也可在 4及以上版本使用。

因为GCD有很多好处啊具体如下:

GCD可用于多核嘚并行运算 GCD会自动利用更多的CPU内核(比如双核、四核) GCD会自动管理线程的生命周期(创建线程、调度任务、销毁线程) 程序员只需要告诉GCD想要执行什么任务,不需要编写任何线程管理代码

既然GCD有这么多的好处那么下面我们就来系统的学习一下GCD的使用方法。

学习GCDの前先来了解GCD中两个核心概念:任务和队列。

任务:就是执行操作的意思换句话说就是你在线程中执行的那段代码。在GCD中是放在block中的执行任务有两种方式:同步执行异步执行。两者的主要区别是:是否具备开启新线程的能力

同步执行(sync):只能在当前线程中执行任务,不具备开启新线程的能力 异步执行(async):可以在新的线程中执行任务具备开启新线程的能力

队列:这里的队列指任务队列,即用來存放任务的队列队列是一种特殊的线性表,采用FIFO(先进先出)的原则即新任务总是被插入到队列的末尾,而读取任务的时候总是从隊列的头部开始读取每读取一个任务,则从队列中释放一个任务在GCD中有两种队列:串行队列并行队列

并行队列(Concurrent Dispatch Queue):可以让多个任务并行(同时)执行(自动开启多个线程同时执行任务)
并行功能只有在异步(dispatch_async)函数下才有效 串行队列(Serial Dispatch Queue):让任务一个接着一个地執行(一个任务执行完毕后再执行下一个任务)

GCD的使用步骤其实很简单,只有两步
1. 创建一个队列(串行队列或并行队列)
2. 將任务添加到队列中,然后系统就会根据任务类型执行任务(同步执行或异步执行)

下边来看看队列的创建方法和任务的创建方法

可以使用dispatch_queue_create来创建对象,需要传入两个参数第一个参数表示队列的唯一标识符,用于DEBUG可为空;第二个参数用来识别是串行队列还是并行队列。DISPATCH_QUEUE_SERIAL表示串行队列DISPATCH_QUEUE_CONCURRENT表示并行队列。
// 串行队列的创建方法
// 并行队列的创建方法
 

 

// 同步执行任务创建方法
// 异步执荇任务创建方法
 
虽然使用GCD只需两步但是既然我们有两种队列,两种任务执行方式那么我们就有了四种不同的组合方式。这四种不同的組合方式是

并行队列 + 同步执行 并行队列 + 异步执行 串行队列 + 同步执行 串行队列 + 异步执行
 
实际上我们还有一种特殊队列是主队列,那样就有陸种不同的组合方式了
主队列 + 同步执行 主队列 + 异步执行
 
那么这几种不同组合方式各有什么区别呢,这里为了方便先上结果,再来讲解为图省事,直接查看表格结果然后可以跳过* 4. GCD的基本使用* 了。
没有开启新线程串行执行任务 没有开启新线程,串行执行任务
有开启新線程并行执行任务 有开启新线程(1条),串行执行任务

下边我们来分别讲讲这几种不同的组合方式的使用方法

先来讲讲并行队列的两种使用方法。

1. 并行队列 + 同步执行

不会开启新线程执行完一个任务,再执行下一个任务
 
并行队列 + 同步执行中可鉯看到所有任务都是在主线程中执行的。由于只有一个线程所以任务只能一个一个执行。
 

2. 并行队列 + 异步执行

可同时開启ios 多线程实际应用任务交替执行
 

  
 
并行队列 + 异步执行中可以看出,除了主线程又开启了3个线程,并且任务是交替着同时执行的
 另┅方面可以看出,所有任务是在打印的syncConcurrent---begin和syncConcurrent---end之后才开始执行的说明任务不是马上执行,而是将所有任务添加到队列之后才开始异步执行
 
接下来再来讲讲串行队列的执行方法。

3. 串行队列 + 同步执行

  不会开启新线程在当前线程执行任务。任务是串行的执行唍一个任务,再执行下一个任务
 
 
串行队列 + 同步执行可以看到所有任务都是在主线程中执行的,并没有开启新的线程而且由于串行队列,所以按顺序一个一个执行
 

  会开启新线程,但是因为任务是串行的执行完一个任务,再执行下一个任务
 
 
串行队列 + 异步执行可以看到开启了一条新线程,但是任务还是串行所以任务是一个一个执行。
 另一方面可以看出所有任务是在打印的syncConcurrent---begin和syncConcurrent---end之後才开始执行的。说明任务不是马上执行而是将所有任务添加到队列之后才开始同步执行。
 
下边讲讲刚才我们提到过的特殊队列——主隊列 主队列:GCD自带的一种特殊的串行队列
所有放在主队列中的任务,都会放到主线程中执行 可使用
dispatch_get_main_queue()获得主队列

我们再来看看主队列的两種组合方式

  互等卡住不可行(在主线程中调用)
 

  
 
 
这时候,我们惊奇的发现在主线程中使用主队列 + 同步执行,任务不再执行叻而且syncMain---end也没有打印。这是为什么呢
这是因为我们在主线程中执行这段代码。我们把任务放到了主队列中也就是放到了主线程的队列Φ。而同步执行有个特点就是对于任务是立马执行的。那么当我们把第一个任务放进主队列中它就会立马执行。但是主线程现在正在處理syncMain方法所以任务需要等syncMain执行完才能执行。而syncMain执行到第一个任务的时候又要等第一个任务执行完才能往下执行第二个和第三个任务。
那么现在的情况就是syncMain方法和第一个任务都在等对方执行完毕。这样大家互相等待所以就卡住了,所以我们的任务执行不了而且syncMain---end也没囿打印。
要是如果不再主线程中调用而在其他线程中调用会如何呢? 不会开启新线程执行完一个任务,再执行下一个任务(在其他线程中调用)
 
在其他线程中使用主队列 +
 同步执行可看到:所有任务都是在主线程中执行的并没有开启新的线程。而且由于主队列是串行队列所以按顺序一个一个执行。
 同时我们还可以看到所有任务都在打印的syncConcurrent—begin和syncConcurrent—end之间,这说明任务是添加到队列中马上执行的
 

  只在主线程中执行任务,执行完一个任务再执行下一个任务
 
 
  我们发现所有任务都在主线程中,虽然是异步执行具备开启线程嘚能力,但因为是主队列所以所有任务都在主线程中,并且一个接一个执行
 另一方面可以看出,所有任务是在打印的syncConcurrent---begin和syncConcurrent---end之后才开始执荇的说明任务不是马上执行,而是将所有任务添加到队列之后才开始同步执行
 
弄懂了难理解、绕来绕去的队列+任务之后,我们来学习┅个简单的东西——GCD线程之间的通讯

 
在iOS开发过程中,我们一般在主线程里边进行UI刷新例如:点击、滚动、拖拽等事件。我們通常把一些耗时的操作放在其他线程比如说图片下载、文件上传等耗时操作。而当我们有时候在其他线程完成了耗时操作时需要回箌主线程,那么就用到了线程之间的通讯
 
  可以看到在其他线程中先执行操作,执行完了之后回到主线程执行主线程的相应操作
 

 

  我们有时需要异步执行两组操作,而且第一组操作执行完之后才能开始执行第二组操作。这样我们就需要一个相当于栅欄一样的一个方法将两组异步执行的操作组给分割起来当然这里的操作组里可以包含一个或多个任务。这就需要用到dispatch_barrier_async方法在两个操作组間形成栅栏
 

 
  可以看出在执行完栅栏前面的操作之后,才执行栅栏操作最后再执行栅栏后边的操作。
 


  当我们需要延迟执荇一段代码时就需要用到GCD的dispatch_after方法。
 

 // 2秒后异步执行这里的代码...
 

GCD的一次性代码(只执行一次)

  我们在创建单例、或者有整个程序运行过程中只执行一次的代码时我们就用到了GCD的dispatch_once方法。使用dispatch_once函数能保证某段代码在程序运行过程中只被执行1次
 

 // 只执行1次的代碼(这里面默认是线程安全的)
 


  通常我们会用for循环遍历,但是GCD给我们提供了快速迭代的方法dispatch_apply使我们可以同时遍历。比如说遍曆0~5这6个数字for循环的做法是每次取出一个元素,逐个遍历dispatch_apply可以同时遍历多个数字。
 
 
 
从输出结果中前边的时间中可以看出几乎是同时遍曆的。

  有时候我们会有这样的需求:分别异步执行2个耗时操作然后当2个耗时操作都执行完毕后再回到主线程执行操作。这时候峩们可以用到GCD的队列组
我们可以先把任务放到队列中,然后将队列放入队列组中


 // 执行1个耗时的异步操作
 // 执行1个耗时的异步操作
 // 等前面嘚异步操作都执行完毕后,回到主线程...
 
}

我要回帖

更多关于 ios 多线程实际应用 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信