1.NSThread 2.Cocoa NSOperation 3.GCD(Grand Central Dispatch)

原创 2015年11月18日 15:31:58

先说一下进程和线程的区别

  • 进城:进程是指在系统中正在运行的一个应用程序,每个进程之间是独立的,每个进程均运行在其专用且受保护的内存空间内.比如说微信,扣扣,微博都是一个进城,他们都有自己的内存空间
  • 线程:1个进程要想执行任务,必须得有线程(每1个进程至少要有1条线程),线程是进程的基本执行单元,一个进程(程序)的所有任务都在线程中执行,比如使用酷狗播放音乐、使用迅雷下载电影,都需要在线程中执行

一,.NSThread

  • 优点:NSThread 比其他两个轻量级
  • 缺点:需要自己管理线程的生命周期,线程同步。线程同步对数据的加锁会有一定的系统开销
  1. 创建方式
    - (id) initWithTarget:<#(nonnull id)#> selector:<#(nonnull SEL)#> object:<#(nullable id)#> //实例方法     
    + (void) detachNewThreadSelector:<#(nonnull SEL)#> toTarget:<#(nonnull id)#> withObject:<#(nullable id)#>//类方法

           注意:NSThread 实例方法需要调用- (void)start方法启动线程

        2.线程锁

           为了防止多个线程访问同一个方法,我们需要为线程加上一把锁

        3.我们可以加上@synchronized来为线程加上同步,这样我们就不用手动为线程加锁了

    @synchronized(<#token#>) {
        <#statements#>
    }

二.Cocoa NSOperation

  • 优点:1.不需要关心线程管理,数据同步的事情,可以把精力放在自己需要执行的操作上。Cocoa operation 相关的类是 NSOperation ,NSOperationQueue。NSOperation是个抽象类,使用它必须用它的子类,可以实现它或者使用它定义好的两个子类:NSInvocationOperation 和 NSBlockOperation。创建NSOperation子类的对象,把对象添加到NSOperationQueue队列里执行。2.如果你也熟悉Java,NSOperation就和java.lang.Runnable接口很相似。和Java的Runnable一样,NSOperation也是设计用来扩展的,只需继承重写NSOperation的一个方法main。相当与java 中Runnalbe的Run方法。然后把NSOperation子类的对象放入NSOperationQueue队列中,该队列就会启动并开始处理它。
  • 缺点:

       

    NSInvocationOperation * operation1 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(printLargeNumber) object:nil];
    NSInvocationOperation * operation2 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(test) object:nil];
    
    NSOperationQueue * queue = [[NSOperationQueue alloc] init];
    //设置最大的并发个数
    [queue setMaxConcurrentOperationCount:2];
    [queue addOperation:operation1];
    [queue addOperation:operation2];
       注意:  线程池中的线程数,也就是并发操作数。默认情况下是-1,-1表示没有限制,这样会同时运行队列中的全部的操作。

三.GCD(Grand Central Dispatch)

  • 介绍:Grand Central Dispatch (GCD)是Apple开发的一个多核编程的解决方法。在iOS4.0开始之后才能使用。GCD是一个替代诸如NSThread, NSOperationQueue, NSInvocationOperation等技术的很高效和强大的技术。现在的iOS系统都升级到7了,所以不用担心该技术不能使用。
  • GCD的工作原理:1.让程序平行排队的特定任务,根据可用的处理资源,安排他们在任何可用的处理器核心上执行任务。2.一个任务可以是一个函数(function)或者是一个block。 GCD的底层依然是用线程实现,不过这样可以让程序员不用关注实现的细节。3.GCD中的FIFO队列称为dispatch queue,它可以保证先进来的任务先得到执行。

        dispatch queue分为下面三种

  1. Serial :又称为private dispatch queues,同时只执行一个任务。Serial queue通常用于同步访问特定的资源或数据。当你创建多个Serial queue时,虽然它们各自是同步执行的,但Serial queue与Serial queue之间是并发执行的。
  2. Concurrent :又称为global dispatch queue,可以并发地执行多个任务,但是执行完成的顺序是随机的。
  3. Main dispatch queue :它是全局可用的serial queue,它是在应用程序主线程上执行任务的。

       dispatch queue如何使用:

         1.常用的方法dispatch_async : 为了避免界面在处理耗时的操作时卡死,比如读取网络数据,IO,数据库读写等,我们会在另外一个线程中处理这些操作,然后通知主线程更新界面。

     

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{   
    // 耗时的操作   
    dispatch_async(dispatch_get_main_queue(), ^{   
        // 更新界面   
    });   
});
优点:1.代码简洁,2.GCD会自动根据任务在多核处理器上分配资源,优化程序

系统给每一个应用程序提供了三个concurrent dispatch queues。这三个并发调度队列是全局的,它们只有优先级的不同。因为是全局的,我们不需要去创建。我们只需要通过使用函数dispath_get_global_queue去得到队列,如下:


dispatch_queue_t globalQ = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

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

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

       2、dispatch_group_async的使用 :dispatch_group_async可以实现监听一组任务是否完成,完成后得到通知执行其他的操作。这个方法很有用,比如你执行三个下载任务,当三个任务都下载完成后你才通知界面说完成的了。下面是一段例子代码:

dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);   
dispatch_group_t group = dispatch_group_create();   
dispatch_group_async(group, queue, ^{   
    [NSThread sleepForTimeInterval:1];   
    NSLog(@"group1");   
});   
dispatch_group_async(group, queue, ^{   
    [NSThread sleepForTimeInterval:2];   
    NSLog(@"group2");   
});   
dispatch_group_async(group, queue, ^{   
    [NSThread sleepForTimeInterval:3];   
    NSLog(@"group3");   
});   
dispatch_group_notify(group, dispatch_get_main_queue(), ^{   
    NSLog(@"updateUi");   
});   
dispatch_release(group);

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

2012-09-25 16:04:16.737 gcdTest[43328:11303] group1 
2012-09-25 16:04:17.738 gcdTest[43328:12a1b] group2 
2012-09-25 16:04:18.738 gcdTest[43328:13003] group3 
2012-09-25 16:04:18.739 gcdTest[43328:f803] updateUi

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

         3、dispatch_barrier_async的使用:dispatch_barrier_async是在前面的任务执行结束后它才执行,而且它后面的任务等它执行完成之后才会执行

例子代码如下:

dispatch_queue_t queue = dispatch_queue_create("gcdtest.rongfzh.yc", DISPATCH_QUEUE_CONCURRENT);   
dispatch_async(queue, ^{   
    [NSThread sleepForTimeInterval:2];   
    NSLog(@"dispatch_async1");   
});   
dispatch_async(queue, ^{   
    [NSThread sleepForTimeInterval:4];   
    NSLog(@"dispatch_async2");   
});   
dispatch_barrier_async(queue, ^{   
    NSLog(@"dispatch_barrier_async");   
    [NSThread sleepForTimeInterval:4];   

});   
dispatch_async(queue, ^{   
    [NSThread sleepForTimeInterval:1];   
    NSLog(@"dispatch_async3");   
});

打印结果:

2012-09-25 16:20:33.967 gcdTest[45547:11203] dispatch_async1 
2012-09-25 16:20:35.967 gcdTest[45547:11303] dispatch_async2 
2012-09-25 16:20:35.967 gcdTest[45547:11303] dispatch_barrier_async 
2012-09-25 16:20:40.970 gcdTest[45547:11303] dispatch_async3

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

        4、dispatch_apply :执行某个代码片段N次。

dispatch_apply(5, globalQ, ^(size_t index) { 
    // 执行5次 
});


本文使用的例子代码参考:http://cache.baiducontent.com/c?m=9d78d513d9981cee4fece4697d62c0156a43f0662ba4d0027fa5843897732c43506793ac56560772a7d20c6616de384bea812102371453bc8cb8fc5daccd866f6fd6286e365ac45613a004b29b18789437902db1f249b7e7ae6584aea582820b4ece5807798bed&p=c4759a46d6c51cfb1281c7710f0089&newp=8f78ce15d9c041a944f3c7710f0589231610db2151ddd60961&user=baidu&fm=sc&query=iOS%BF%AA%B7%A2+%B6%E0%CF%DF%B3%CC+%B2%A9%BF%CD&qid=fa5b06890000b490&p1=3




四.不显式创建线程的方法

[id performSelectorInBackground:<#(nonnull SEL)#> withObject:<#(nullable id)#>] //创建了一个子线程
[self performSelectorOnMainThread:<#(nonnull SEL)#> withObject:<#(nullable id)#> waitUntilDone:<#(BOOL)#>] //  回到主线程


版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

iOS三种多线程技术NSThread,NSOperation/NSOperationQueue,GCD-Grand Central Dispatch

一.NSThread 建立一个线程方便,但是要使用NSThread管理多个线程非常困难,只要记住以下几个方法. (1) [NSThread currentThread] //跟踪任务所在线程,适用于这...

IOS_多线程_NSThread+NSOperation+GCD(Grand Central Dispatcher)

H:/0729/01_对象方法创建NSThread+加锁+售票_ViewController.h// ViewController.h // 卖票 // Created by apple on ...

[IOS/翻译]GCD-1 Grand Central Dispatch

本文是本人自己辛苦翻译的,请转载的朋友注明,翻译于Z.MJun的CSDN的博客 http://blog.csdn.net/Zheng_Paul,感谢! 翻译于2016年5月12日Grand ...

GCD(Grand Central Dispatch)和Block 使用-浅析 (2

关于GCD,我想我前面的有些博客已经介绍的很清楚了。我们就来谈一下它单纯的入门级别的应用。 Grand Central Dispatch,或者简称 GCD,是一个与 Block ...

转 Grand Central Dispatch 基础教程:Part 1/2 -swift

本文转载,原文地址:http://www.cocoachina.com/ios/20150609/12072.html  原文 Grand Central Dispatch Tutorail...

Grand Central Dispatch 基础教程:Part 1/2

原文 Grand Central Dispatch Tutorail for Swift: Part 1/2 原文作者:Bjrn Olav Ruud 译者:Ethan Joe ...

A Guide to Blocks & Grand Central Dispatch (and the Cocoa API's making use of them)

Intro As you may or may not know I recently did a talk at the Des Moines Cocoaheads in which I revie...

iOS多线程编程之Grand Central Dispatch(GCD)介绍和使用

介绍: Grand Central Dispatch 简称(GCD)是苹果公司开发的技术,以优化的应用程序支持多核心处理器和其他的对称多处理系统的系统。这建立在任务并行执行的线程池模式的基础上的。它...
  • sadlike
  • sadlike
  • 2016年08月24日 15:46
  • 153

iOS多线程编程之Grand Central Dispatch(GCD)介绍和使用

著作权声明:本文由http://blog.csdn.net/totogo2010/原创,欢迎转载分享。请尊重作者劳动,转载时保留该声明和作者博客链接,谢谢! 介绍: Gra...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:1.NSThread 2.Cocoa NSOperation 3.GCD(Grand Central Dispatch)
举报原因:
原因补充:

(最多只允许输入30个字)