IOS 多线程03-GCD

如果在本文之前要了解一下线程的基本知识,请访问下面的网址:http://www.cnblogs.com/alunchen/p/5337608.html

1.简介

  GCD不仅适用于Object-C,也适用于C、C++

  GCD在C接口中添加了一些优秀的概念,比如工作单元、无痛后台处理(painless background processing)、自动线程管理,他们可在所有基于C的语言中使用。

  GCD的重要一个概念是队列,可以保证始终在主线程上执行工作的队列,非常适合非线程安全的UIKit。也可以自己创建队列。

  GCD队列遵循FIFO(先进先出)原则

2.使用之前-block

  在使用GCD之前,一定要理解新语法block的使用,对于尽量充分利用GCD非常重要。block可替代object-c中的委托模式或C中的回调函数。这里不详细介绍block了,请参照下面文章 http://www.cnblogs.com/alunchen/p/5341057.html

3.开启新线程与主线程

  下面我们用GCD开启一个新线程。注意的是当我们执行下面的方法,当执行完doSomething(),其实startTime已经释放了,但是注意的block一个关键点是,如果一个程序块block在执行过程中访问任何的‘外部’变量,那么该程序块block被创建时会进行一些特殊的设置工作,以允许程序块访问这些变量。所以,其实在调用dispatch_async时,startTime被retain了一次,而且程序块block内部赋给了一个内部同名startTime的新的不可变的变量。

-(void) doSomething()  {
    NSDate *startTime = [NSDate date];
    //取得一个全局队列,优先级为DISPATCH_QUEUE_PRIORITY_DEFAULT
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    //开启异步线程
    dispatch_async(queue, ^{ 
       //在这里做一些任何耗时的处理
        NSDate *endTime = [NSDate date];
       NSLog(@"完成时间:%f", [endTime timeIntervalSinceDate: startTime]);
    }); 
}

  上面创建了一个异步线程,但是我们想要在异步线程中做任何更新等UI操作是不可能的,下面例子是执行完线程后,获取主线程做UI操作:

-(void) doSomething()  {
    NSDate *startTime = [NSDate date];
    //取得一个全局队列,优先级为DISPATCH_QUEUE_PRIORITY_DEFAULT
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    //开启异步线程
    dispatch_async(queue, ^{ 
       //在这里做一些任何耗时的处理

       //得到主线程,做UI操作
        dispatch_async(dispatch_get_main_queue(), ^{ 
            //在这里做一些更新UI等UI操作
       
       }); 
    }); 
}

4.并发程序块-dispatch group(提高执行速度)

   如果在新开启的异步线程A中,运行需要的时间大概需要10秒,那么我们想象一下,这个运行时间会不会太长。现在,IOS提供了一个dispatch group分派组给我们快速的执行。原理是将一个组的上下文中通过dispatch_group_async()函数异步分派的所有程序块同时运行,那就不需要10秒那么长的时间了。也可以使用dispatch_group_notify()指定一个额外的程序块,让它在组中的所有程序块运行完成时再执行。可看下面例子:

//上面的doSomething()需要10秒,这里的少于10秒
-(void) doSomething()  {
    NSDate *startTime = [NSDate date];
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    //开启异步线程
    dispatch_async(queue, ^{ 
       //在这里做一些任何耗时的处理
       doSomething2();

       //这里开始定义group
       dispatch_group_t group = dispatch_group_create();
       dispatch_group_async(group, queue,  ^{ 
               //这里这一些其他的耗时处理
               doSomething3();
       });
       
       //等待上面所有的线程运行完,这里才执行(notify的作用)
       dispatch_group_notify(group, queue, ^{
               dispatch_async(dispatch_get_main_queue(), ^{
                       //做一些主线程更新UI的操作
                       doSomethingWithUI();
               });
       });

    }); 
}
原文地址:https://www.cnblogs.com/alunchen/p/5338086.html