GCD 小结

来源:互联网 发布:百知java培训 编辑:程序博客网 时间:2024/04/28 13:37
  

  iOS 多线程编程技术

1. Cocoa 封装 Thread : NSThread  轻量级  performselector

2. Cocoa 封装的 NSoperation 

3. GCD  grand Central Dispatch


三种编程方式从上到下, 抽象层次从低到高, 也就是 GCD是抽象程度最高的, 所有用起来也是最顺手的;


 三种方式的优缺点分析 

  NSThread  和 POSIX threads

NSThread 更加轻量级, 缺点: 需要自己管理线程的生命周期,线程同步,对数据的加锁 , 会有一定的系统开销, 即稍微会阻塞一点点;


  Cocoa operation 

  优点: 不需要关心线程管理,数据同步的事情, 可以把精力放在自己需要执行的操作上;

operation 相关的类是 NSOperation, NSOperationQueue. NSOperation 是个抽象类;


可以这么理解: 抽象类的实例也是类 , 所以必须使用其子类的对象去操作

这个抽象类有哪些实例呢 , 自定义 NSOperaton  ; 或者使用系统原生提供的两个类

NSInvocationOperation 和 NSBlockOpeation , 创建 NSoperation 的子类对象添加到 NSOperationQueue 队列里执行;



 GCD : 是 Apple 多核编程的解决方案,相对于NSOperation 来讲,抽象度最高,也最方便使用;

GCD 可以替代 NSThread, NSOperationQueue, NSInvocationOperation 等技术;



NSThread 的使用


实例方法 监听 selector源

- (id)initWithTarget:(id)target selector:(SEL)selector object:(id)argument;

分离出一个新的线程 监听 selector 方法;

+’(void)detachNewThreadSelector:(SEL)aSelector toTarget:(id)aTarget withObject:(id)anArgument ;


selector 源线程执行的方法,这个selector只能有一个参数,而且不能有返回值。



PS : 不显式创建线程的方法:

用 NSObject 类方法 performSelectorInBackground:withObject; 创建一个线程;


2.4.2 线程之间的通讯

线程下载完图片后怎么通知主线程更新 UI

[self performSelectorOnMainThread:@selector (updateUI:)withObject:image waitUntilDone:Yes];

performSelector:onThread:withObject:waitUntilDone;



NSOperation 的方式有两种

NSInvocationOperation 和 NSBlockOperation

另一种继承是 NSOperation 

如果你熟悉 Java , NSOperation 和 java.lang.Runnable 接口类似, NSOperation 也是设计用来扩展的,只需继承重写 NSOperation 的一个 main 方法, 相当于 Runnable 中的 Run 方法;


NSInvocationOperation *operation = [NSInvocationOperation alloc]initwithTarget:self sector:@selector(downloadImage:) object:KURL];


在 view DidLoad 里面建立一个后台线程; 并且放到 NSOperation Queue 中底层会执行;

NSOperationQueue *queue = [[NSOperationQueue alloc]init];  

    [queue addOperation:operation];  

         在继承 NSOperation 类,在.m文件中实现main方法,main方法编写要执行的代码即可。,即在 main.m 中写扩展;


控制线程池中的线程数;

队列里可以加入很多个NSOperation, 可以把NSOperationQueue看作一个线程池,可往线程池中添加操作(NSOperation)到队列中。线程池中的线程可看作消费者,从队列中取走操作,并执行它。

通过下面的代码设置:
[queue setMaxConcurrentOperationCount:5];
线程池中的线程数,也就是并发操作数。默认情况下是-1-1表示没有限制,这样会同时运行队列中的全部的操作。

    可以在 Operation 操作上添加依赖顺序,来控制线程的响应的顺序;


   GCD  建立在任务并行执行的线程池的模式基础上的. 它首次发布在Mac OS X 10.6 , iOS 4 以上使用

GCD 的工作原理: 让程序平行排队的特定任务,根据可用的处理器,安排他们在任何可用的处理器核心上执行任务;



FIFO 队列称为dispatch queue 

又称为私有 P 队列

serial : privateprivate dispatch queues 同时只执行一个任务, Serial  queue 通常用于同步访问特定的资源或数据

当创建多个 Serial queue 时, 他们自身是同步的, 之间是并发的; 执行顺序完全是随机的


Concurrent: G 队列

又称为全局队列,可以并发执行多个任务,但是执行完成的顺序是随机的


Main dispatch queue  : M 队列

应用主程上执行任务的,全局的 serial queue ’



系统给每一个应用程序提供三个 concurrent dispatch queues ,(default) 这三个并发队列是全局的,优先级不同

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


dispatch_queue虽然dispatch queue是引用计数的对象,但是以上两个都是全局的队列,不用retainrelease_t mainQ = dispatch_get_main_queue();   



dispatch_group_async 的使用

group_async 可以实现监听一组任务是否完成, 完成后得到通知执行其他操作, 这个方法有用,比如你执行三个下载任务,当三个任务都下载完成后,你才通知界面说完成的了;


dispatch_barrier_async 是在前面的任务执行结束后他才执行,而且它后面的任务等它执行完成之后才会执行


dispatch_apply

执行某个代码片段 N 次



本篇使用的到的例子代码:http://download.csdn.net/detail/totogo2010/4596471

GCD还有很多其他用法,可以参考官方文档

参考的文档还有:http://en.wikipedia.org/wiki/Grand_Central_Dispatch

前两篇多线程博文:iOS多线程编程之NSThread的使用

    iOS多线程编程之NSOperationNSOperationQueue的使用




锁对象 : NSConditon , NSConditionLock , NSRecursiveLock;


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

线程的顺序执行

他们都可以通过 NSCondition 有一个 signal 属性

        [ticketsCondition signal]; 发送信号的方式,在一个线程唤醒另外一个线程的等待。

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


循环锁NSRecursiveLock,条件锁NSConditionLock,分布式锁NSDistributedLock等等,


我们可以使用指令 @synchronized {}来简化 NSLock的使用,这样我们就不必显示编写创建NSLock,加锁并解锁相关代码。

0 0
原创粉丝点击