多线程的意义:经过提升系统资源的利用率,充分发挥多核处理器的优点,并发(同时执行)执行任务让系统运行的更快、更流畅多线程
NSThread(目前已经不经常使用)并发
在NSThread多线程中最经常使用的是NSObject封装的多线程方法框架
-(void)performSelectorInBackground:(SEL)aSelector withObject:(id)arg异步
这个方法能够调用继承自对象中实现的方法经过将其抛入到其余后台线程执行async
(SEL即为须要调用的selector; arg为向selector中传递的参数)函数
这个方法能够修改程序的UI可是强烈不建议使用该方法直接修改界面.spa
若是须要在该方法中修改UI能够调用控件的线程
-(void)performSelectorOnMainThread:(SEL)aSelector withObject:(id)arg waitUntilDone:(BOOL)wait;设计
方法来进行修改orm
performSelectorOnMainThread方法也是在nsobject类中封装的多线程方法,该方法的做用是调用对象中的方法在主线程中执行
固然也可使用自定义线程的方式来实现多线程:
+(void)detachNewThreadSelector:(SEL)selector toTarget:(id)target withObject:(id)argument;
NSThread的工厂方法,快速返回一个NSThread对象,该方法生成的线程会直接启动
-(id)initWithTarget:(id)target selector:(SEL)selector object:(id)argument;
NSthread的构造函数生成一个NSThread对象,该方法生成的线程对象须要手动调用start方法才能启动
须要注意的是在NSThread方式实现多线程的时候须要给每个线程定义一个autoreleasepool,不然会出现内存泄露
NSOperation/NSOperationQueue
这是一种面向对象的多线程技术, 因其对另外两种进行了封装,因此相比较其余两种有更加全面的功能;
通常步骤:
建立一个NSOperation
建立或者获取一个NSOperationQueue
将操做添加到队列中
NSOperation分为两个子类
NSInvocationOperation
- (id)initWithTarget:(id)target selector:(SEL)sel object:(id)arg;
这个方法有些相似于NSThread 主要就是须要把抛出的操做封装到target的一个对象方法中,能够传一个参数;
NSBlockOperation(我的感受最好用的)
+ (id)blockOperationWithBlock:(void (^)(void))block;
工厂方法快速生成一个blockOperation,该方法的好处就是不须要再定义一个方法,而block做为一个参数传递进去能够极大地加强代码的扩展性,下降代码间的耦合度,方便后期维护.
建立好了nsoperation以后就须要将它添加到指定的队列中去了当操做被加入到队列中的时候就马上处于激活状态开始执行了;
NSOperation的start方法能够将该操做加入到当前的操做队列中.
另外,值得一提的是NSOperation方式实现多线程相比较其余两种最大的好处就是能够限制并发的线程数
-(void) maxConcurrentOperationCount;
这个方法是NSOperationQueue的对象方法,用来限制当前操做队列同时并发的线程数
在一个程序中,每多开一个线程就会多占用一些系统资源,在iOS环境下主线程的栈内存是1M以后每开一个子线程会占用系统512k的栈内存,因此在实际的开发中控制并发的线程数是很是重要的.
NSOperation对象之间的依赖关系:
在多线程开发中,若是几个操做之间有依赖关系是很是使人头疼的一件事,可是NSOperation能够很简单的处理不一样线程之间的操做依赖关系例如,有三个操做分别为op1, op2, op3.三个操做须要按照顺序执行代码以下:
[op2 addDependency:op1];
[op3 addDependency:op2];
这种依赖关系并不受所在的操做队列限制也就是说,即便op1,op2处于子线程并且是很是耗时的操做,op3处于主线程.op3也会等到op2执行完毕后才会执行,这样在实际的开发中是很是方便的,由于在开发中操做队列中的操做并非按照添加顺序来执行的,而添加依赖就保证了它们可以按照规定的顺序执行
Gcd
GCD 是一套基于C语言的框架,发布于iOS4.0,其设计的初衷就是为了更好的发挥多核处理器的优点,底层是经过线程实现的,GCD是苹果官方推荐使用的多线程技术;
首先介绍一下GCD的三种队列:
全局队列:全部添加到该队列的任务都是并发执行的;
串行队列:全部添加到串行队列的任务都是顺序执行的;
主队列:添加到主队列中的任务都是在主线程执行的;
各队列的获取方法:
全局队列:
dispatch_queue_t queue=dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0)
参数说明:第一个参数是该队列的优先级,建议使用默认,若无特殊要求最好不要随意设置优先级
第二个参数是预留参数,须要填0
串行队列:
dispatch_queue_t queue = dispatch_queue_create("myQueue", DISPATCH_QUEUE_SERIAL);
参数说明:这是一个建立队列的方法,第一个参数是队列名这个能够本身随意,第二个参数有两个值DISPATCH_QUEUE_SERIAL表示建立一个串行队列
DISPATCH_QUEUE_CONCURRENT表示建立一个并行队列(感受意义不大由于已经有了全局队列)
主队列: dispatch_queue_t queue =dispatch_get_main_queue();
以上就是三种队列的获取方法
下面开始介绍GCD中任务执行方法
GCD任务执行分为同步方法和异步方法,其实实际是同步仍是异步须要方法名和执行队列共同来决定的,这就须要读者本身多去练习才能彻底理解
首先是异步方法
dispatch_async(dispatch_queue_t queue, dispatch_block_t block);
参数:第一个参数为执行队列第二个参数是任务的代码块
同步方法:
dispatch_sync(dispatch_queue_t queue, dispatch_block_t block);
参数与异步方法传入参数同样
这里因为有两种执行方法,四种队列组合方式实在是太多,我也就不一一列举了,若是想要了解GCD其实最直接的方法就是,分别给两种方法传入不一样的队列,而后按照各类顺序调用,只有多练习才能彻底掌握;
其实GCD在实际使用中是很是简单的
只须要两步而已:
第一步获取一个执行队列,第二步将操做同步或者异步的加入到执行队列中去
注:示例代码我在找一个比较稳定的网盘,因此会稍后上传