您的位置:首页 > 其它

GCD 小结

2016-03-27 16:36 316 查看
  
  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是引用计数的对象,但是以上两个都是全局的队列,不用retain或release。_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多线程编程之NSOperation和NSOperationQueue的使用

锁对象 : NSConditon , NSConditionLock , NSRecursiveLock;

上面例子我使用了两种锁,一种NSCondition
,一种是:NSLock。 NSCondition我已经注释了。
线程的顺序执行
他们都可以通过 NSCondition 有一个 signal 属性
        [ticketsCondition signal]; 发送信号的方式,在一个线程唤醒另外一个线程的等待。
wait是等待,我加了一个
线程3 去唤醒其他两个线程锁中的wait

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

我们可以使用指令 @synchronized {}来简化 NSLock的使用,这样我们就不必显示编写创建NSLock,加锁并解锁相关代码。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: