潘小龙
【摘要】 随着苹果手机在智能手机市场取得的成功,iOS系统也在被广大用户熟识和喜爱,其内部架构设计也在被越来越多的技术开发人员所剖析、研究和运用。本文从多线程的相关概念出发,对iOS系统中主流的三种多线程实现技术进行了研究和分析,并通过分析比较,总结了三者之间的不同以及优缺点,将对相关系统开发起到借鉴意义。
【关键词】 iOS系统 多线程 NSThread GCD NSOperation
一、引言
从2007年第一代iPhone推出至今历经了六代的发展,苹果手机已经成为智能手机市场举足轻重的一员,除去时尚的外表,卓越的性能和绝佳的用户体验也是苹果手机长盛不衰的重要原因,而这正离不开iOS系统中对多线程技术的设计和实现。
本文将以多线程概念为切入点,对比分析三种主要的多线程技术并分析各自优缺点,最后给出了在实际开发过程中应侧重采用哪种技术的建议。
二、多线程概述
2.1 进程与线程
进程是指正在运行中的程序,它负责程序运行时的内存分配,每一个进程都有自己独立的虚拟内存空间。
线程是进程中一个独立的控制单元,一个进程中至少包含一条线程,即主线程,在程序运行时,可以将耗时的执行路径放在其他线程中执行,线程不能被终结,但是可以被暂停或者休眠。
2.2 多线程概念
多线程(multithreading),指的是在软件或硬件上让多个线程实现并发执行的技术。一台计算机具有多线程能力,再加上硬件的支持,因而能够在同一时间执行多于一个线程,进而使整体处理性能得到提升。具有这种能力的处理器包括对称多处理机、多核心处理器以及芯片级多处理或同时多线程处理器。
2.3 iOS系统中的线程
在iOS系统程序启动中,创建好一个进程的同时,一个线程便开始运行,这个线程叫主线程。主线程在程序中的地位和其他线程不同,它是其他线程最终的父线程,且所有界面的显示操作即UIKit的操作必须在主线程进行。iOS每个进程中可以开启多个线程,由操作系统分配短暂的时间片轮流使用CPU,由于CPU对每个时间片的处理速度非常快,因此,从用户使用角度来看,任务是同时执行的。
三、iOS系统中三种多线程技术研究
3.1 NSThread多线程实现
NSThread是iOS系统多线程实现技术里相对轻量级的,但也是使用起来需要开发人员自己维护的:需要自己管理thread的生命周期,线程之间的同步等等问题。当不同线程需要共享同一应用程序的部分内存空间时,它们拥有对数据相同的访问权限,这就需要开发人员协调多个线程对同一数据的访问,而这种协调操作会导致一定的性能开销。
NSThread的初始化有静态和动态两种方法:
静态实现方法:
+(void)detachNewThreadSelector:(SEL)selector toTarget:(id)target withObject:(id)argument;
动态实现方法:
-(id)initWithTarget:(id)target selector:(SEL)selector object:(id)argument;
其中,selector:线程执行的方法,这个selector最多只能接收一个参数;target:selector消息发送的对象;argument: 传给selector的唯一参数,也可以是nil。
这两种方式的区别是:前者在实现后就会立即创建一个线程来做事情;而后者虽然初始化完成,但是需要手动调用start启动线程时才会真正去创建线程。
3.2 GCD多线程实现
GCD(Grand Central Dispatch),是基于C语言的底层API。GCD的基本概念就是dispatch queue。dispatch queue是一个对象,它可以接受任务,并将任务以先到先执行的顺序来执行。dispatch queue可以是并发的或串行的。并发任务会像NSOperationQueue那样基于系统负载来合适地并发进行,串行队列同一时间只执行单一任务。
GCD的基本思想就是将操作放在队列中去执行,要使用队列,首先需要调用函数dispatch_queue_create进行创建,队列负责调度任务执行所在的线程以及具体的执行时间。其次向一个队列提交操作,通过调用dispatch_async函数,传入一个队列和一个操作。队列会在轮到这个block执行时执行该操作。
GCD中有四种主要队列:
串行队列:同步操作不会新建線程,操作顺序执行;异步操作会新建线程,操作顺序执行。
并行队列:同步操作不会新建线程,操作顺序执行;异步操作会新建多个线程,操作无序执行,队列前如果有其他任务,会等待前面的任务完成之后再执行。
全局队列:全局队列是系统的,直接GET即可,与并行队列类似,但调试时,无法确认操作所在队列。
主队列:每一个应用程序都对应唯一的主队列,直接GET即可,在多线程开发中,使用主队列更新UI。
总之,队列不是线程,也不表示对应的CPU,队列就是负责调度的。多线程技术的目的,就是为了在一个CPU上实现快速切换。
3.3 NSOperation&NSOperationQueue多线程实现
NSOperation是GCD提供队列模型的Cocoa抽象,是一套Objective-C的API,而NSOperationQueue(操作队列)则在GCD之上实现了一些方便的功能,这些功能对开发者而言通常是最好最安全的选择。
NSOperationQueue与GCD相同,都是依靠队列来完成多线程操作,它其中有两种不同类型的队列:运行在主线程上的主队列和在后台执行的自定义队列。NSOperation是抽象的父类,要进行队列处理任务时都需要继承实现其两个子类:NSInvocationOperation和NSBlockOperation。
使用NSOperation实现多线程调度操作时,同样需要定义队列,在定义完成之后需要定义要进行的操作,最后把定义的操作加入到队列中。
从本质上看, NSOperationQueue操作队列的性能会比GCD略低,不过,大多数情况下这点负面影响可以忽略不计,操作队列是并发编程的首选工具。
四、三种多线程技术的总结比较
4.1 NSThread技术
优点:相对于其他两种技术,NSThread是最轻量级的,易于上手使用,适合iOS初学者使用。
缺点:不能控制线程的数量以及执行顺序,开发人员需要自己管理thread的生命周期,线程之间的同步等问题,因此容易出现开发漏洞。
4.2 GCD技术
优点:基于C语言的底层API封装,因此在进行多线程开发时可以传block,也可以传c函数指针,用于多核编程,方便高效。所有的多线程代码集中在一起,便于维护,GCD中无需使用@autoreleasepool。
缺点:对C语言陌生的开发人员来说理解可能存在一定困难,而且GCD一种轻量级的方法来实现多线程,控制起来比较麻烦,比如取消和暂停一个线程,以及在线程中不同操作之间的依赖关系。
4.3 NSOperation技术
优点:基于GCD的Object-C的封装,与iOS开发适应性更强,同时因其为面相对象封装,所以在操作不同线程任务之间的依赖上更加方便,开发人员不需要关心线程管理,数据同步的事情,可以把精力放在自己需要执行的操作上。
缺点:因为是对GCD的再一次封装,在性能上较GCD略低。
五、结语
通过以上对iOS系统中三种主要多线程技术的研究和比较,可以得出,在实际开发过程中,开发人员应尽量避免采用轻量级的NSThread,而主要采用GCD与NSOperation实现多线程操作,这样可以把更多的精力放在应用程序自身的业务逻辑当中。另外,随着iOS系统的持续更新,开发人员自身技术的不断提高,相信在未来还会出现更好的多线程技术来推动iOS系统的发展。
参 考 文 献
[1]骆斌,费翔林.多线程技术的研究与应用[J].計算机研究与发展, 2000,(04):407-412.
[2]萨丹.iPhone开发秘籍[M].北京:人民邮电出版社,2010:1.
[3]Gene Blacklin(美)著.岳红 凌冲译.iPhone&iPad高级编程[M].北京:清华大学出版社,2012:1.
[4]虞斌著.Ios软件开发解密[M].北京:电子工业出版社,2011:1.
[5]乔纳森(美)著.AppStore掘金[M].北京:人民邮电出版社,2010:1.