iOS有三种多线程编程的技术

1.NSThreadhtml

2.NSOperationQueuejava

3.GCD Threadios

是这三种范式里面相对轻量级的,但也是使用起来最负责的,你须要本身管理thread的生命周期,线程之间的同步。线程共享同一应用程序的部份内存空间, 它们拥有对数据相同的访问权限。你得协调多个线程对同一数据的访问,通常作法是在访问以前加锁,这会致使必定的性能开销。在 iOS 中咱们可使用多种形式的 thread: Cocoa threads: 使用NSThread 或直接从 NSObject 的类方法 performSelectorInBackground:withObject: 来建立一个线程。若是你选择thread来实现多线程,那么 NSThread 就是官方推荐优先选用的方式。 Cocoa operations是基于 Obective-C实现的,类 NSOperation 以面向对象的方式封装了用户须要执行的操做,咱们只要聚焦于咱们须要作的事情,而没必要太操心线程的管理,同步等事情,由于NSOperation已经为我 们封装了这些事情。 NSOperation 是一个抽象基类,咱们必须使用它的子类。iOS 提供了两种默认实现:NSInvocationOperation 和 NSBlockOperation。 Grand Central Dispatch (GCD): iOS4 才开始支持,它提供了一些新的特性,以及运行库来支持多核并行编程,它的关注点更高:如何在多个 cpu 上提高效率。git

 

 

具体实施程序员

 

这三种编程方式从上到下,抽象度层次是从低到高的,抽象度越高的使用越简单,也是Apple最推荐使用的。github

三种方式的优缺点介绍:
1)NSThread:
优势:NSThread 比其余两个轻量级
缺点:须要本身管理线程的生命周期,线程同步。线程同步对数据的加锁会有必定的系统开销数据库

NSThread实现的技术有下面三种:
~MA59HJ2_9MN7%]4Y%}FDGW
通常使用cocoa thread 技术。编程

Cocoa NSOperation
优势:不须要关心线程管理,数据同步的事情,能够把精力放在本身须要执行的操做上。
Cocoa operation 相关的类是 NSOperation ,NSOperationQueue。
NSOperation是个抽象类,使用它必须用它的子类,能够实现它或者使用它定义好的两个子类:NSInvocationOperation 和 NSBlockOperation。
建立NSOperation子类的对象,把对象添加到NSOperationQueue队列里执行。网络

GCD
Grand Central Dispatch (GCD)是Apple开发的一个多核编程的解决方法。在iOS4.0开始以后才能使用。GCD是一个替代诸如NSThread, NSOperationQueue, NSInvocationOperation等技术的很高效和强大的技术。如今的iOS系统都升级到7了,因此不用担忧该技术不能使用。多线程

介绍完这三种多线程编程方式,本文将依次介绍这三种技术的使用。

(一)NSThread的使用
NSThread 有两种直接建立方式:

第一个是实例方法,第二个是类方法

参数的意义:
selector :线程执行的方法,这个selector只能有一个参数,并且不能有返回值。
target  :selector消息发送的对象
argument:传输给target的惟一参数,也能够是nil

第一种方式会直接建立线程而且开始运行线程,第二种方式是先建立线程对象,而后再运行线程操做,在运行线程操做前能够设置线程的优先级等线程信息

不显式建立线程的方法:
用NSObject的类方法  performSelectorInBackground:withObject: 建立一个线程:

下载图片的例子:
新建singeView app
新建项目,并在xib文件上放置一个imageView控件。按住control键拖到viewController.h文件中建立imageView IBOutlet ViewController.m中实现:

线程间通信
线程下载完图片后怎么通知主线程更新界面呢?

performSelectorOnMainThread是NSObject的方法,除了能够更新主线程的数据外,还能够更新其余线程的好比:

运行下载图片:
VFE8W}]XP~E6K0RPJK10EIU

线程同步
咱们演示一个经典的卖票的例子来说NSThread的线程同步:

 

若是没有线程同步的lock,卖票数多是-1.加上lock以后线程同步保证了数据的正确性。

上面例子我使用了两种锁,一种NSCondition ,一种是:NSLock。 NSCondition我已经注释了。

线程的顺序执行
他们均可以经过[ticketsCondition signal]; 发送信号的方式,在一个线程唤醒另一个线程的等待。

好比:

wait是等待,我加了一个 线程3 去唤醒其余两个线程锁中的wait。

其余同步
咱们可使用指令 @synchronized 来简化 NSLock的使用,这样咱们就没必要显示编写建立NSLock,加锁并解锁相关代码。

还有其余的一些锁对象,好比:循环锁NSRecursiveLock,条件锁NSConditionLock,分布式锁NSDistributedLock等等,能够本身看官方文档学习

NSThread下载图片的例子代码:http://download.csdn.net/detail/totogo2010/4591149

(二)Cocoa NSOperation的使用
使用 NSOperation的方式有两种,
一种是用定义好的两个子类:NSInvocationOperation 和 NSBlockOperation。
另外一种是继承NSOperation

若是你也熟悉Java,NSOperation就和java.lang.Runnable接口很类似。和Java的Runnable同样,NSOperation也是设计用来扩展的,只需继承重写NSOperation的一个方法main。至关与java 中Runnalbe的Run方法。而后把NSOperation子类的对象放入NSOperationQueue队列中,该队列就会启动并开始处理它。

NSInvocationOperation例子:
这里一样,咱们实现一个下载图片的例子。新建一个Single View app,拖放一个ImageView控件到xib界面。
实现代码以下:

代码注释:
1.viewDidLoad方法里能够看到咱们用NSInvocationOperation建了一个后台线程,而且放到2.NSOperationQueue中。后台线程执行downloadImage方法。
3.downloadImage 方法处理下载图片的逻辑。下载完成后用performSelectorOnMainThread执行主线程updateUI方法。
updateUI 并把下载的图片显示到图片控件中。

运行能够看到下载图片显示在界面上。
thjyjytktfb464dfgbdgw4

第二种方式继承NSOperation 
在.m文件中实现main方法,main方法编写要执行的代码便可。

如何控制线程池中的线程数?
队列里能够加入不少个NSOperation, 能够把NSOperationQueue看做一个线程池,可往线程池中添加操做(NSOperation)到队列中。线程池中的线程可看做消费者,从队列中取走操做,并执行它。

经过下面的代码设置:

线程池中的线程数,也就是并发操做数。默认状况下是-1,-1表示没有限制,这样会同时运行队列中的所有的操做。

(三)GCD的介绍和使用
介绍:
Grand Central Dispatch 简称(GCD)是苹果公司开发的技术,以优化的应用程序支持多核心处理器和其余的对称多处理系统的系统。这创建在任务并行执行的线程池模式的基础上的。它首次发布在Mac OS X 10.6 ,iOS 4及以上也可用。

设计:
GCD的工做原理是:让程序平行排队的特定任务,根据可用的处理资源,安排他们在任何可用的处理器核心上执行任务。

一个任务能够是一个函数(function)或者是一个block。 GCD的底层依然是用线程实现,不过这样可让程序员不用关注实现的细节。

GCD中的FIFO队列称为dispatch queue,它能够保证先进来的任务先获得执行。

dispatch queue分为下面三种:
Serial 
又称为private dispatch queues,同时只执行一个任务。Serial queue一般用于同步访问特定的资源或数据。当你建立多个Serial queue时,虽然它们各自是同步执行的,但Serial queue与Serial queue之间是并发执行的。

Concurrent 
又称为global dispatch queue,能够并发地执行多个任务,可是执行完成的顺序是随机的。

Main dispatch queue 
它是全局可用的serial queue,它是在应用程序主线程上执行任务的。

咱们看看dispatch queue如何使用?

一、经常使用的方法dispatch_async
为了不界面在处理耗时的操做时卡死,好比读取网络数据,IO,数据库读写等,咱们会在另一个线程中处理这些操做,而后通知主线程更新界面。

用GCD实现这个流程的操做比前面介绍的NSThread  NSOperation的方法都要简单。代码框架结构以下:

若是这样还不清晰的话,那咱们仍是用上两篇博客中的下载图片为例子,代码以下:

运行显示:
fdgrehrthjytjasf4535gfn

是否是代码比NSThread  NSOperation简洁不少,并且GCD会自动根据任务在多核处理器上分配资源,优化程序。

系统给每个应用程序提供了三个concurrent dispatch queues。这三个并发调度队列是全局的,它们只有优先级的不一样。由于是全局的,咱们不须要去建立。咱们只须要经过使用函数dispath_get_global_queue去获得队列,以下:

这里也用到了系统默认就有一个串行队列main_queue:

虽然dispatch queue是引用计数的对象,可是以上两个都是全局的队列,不用retain或release。

二、dispatch_group_async的使用
dispatch_group_async能够实现监听一组任务是否完成,完成后获得通知执行其余的操做。这个方法颇有用,好比你执行三个下载任务,当三个任务都下载完成后你才通知界面说完成的了。下面是一段例子代码:

dispatch_group_async是异步的方法,运行后能够看到打印结果:

每一个一秒打印一个,当第三个任务执行后,upadteUi被打印。

三、dispatch_barrier_async的使用
dispatch_barrier_async是在前面的任务执行结束后它才执行,并且它后面的任务等它执行完成以后才会执行
例子代码以下:

打印结果:

请注意执行的时间,能够看到执行的顺序如上所述。

四、dispatch_apply 
执行某个代码片断N次。

本篇使用的到的例子代码:http://download.csdn.net/detail/totogo2010/4596471
GCD还有不少其余用法,能够参考官方文档http://en.wikipedia.org/wiki/Grand_Central_Dispatch

相关文章
相关标签/搜索