上一节,主要介绍了GCD的基本的概念,这节将用代码深入详细介绍GCD的使用。
一  使用介绍

   GCD的使用主要分为三步:创建代码块;选择或创建合适的分发队列;(同步、异步方式)向分发队列提交任务

1.创建代码块

   提交到GCD中的代码块,是没有返回值的,他们都是dispatch_block_t类型的代码块,dispatch_queue_t 的定义如下:
 typedef void (^dispatch_block_t)( void)
       意味着加入 dispatch_queue 中的 block 必须是无参数也无返回值的。除了用代码块封装task外,我们也可以使用C语言函数来编写,然后将其提交到分发队列中,但是一般情况下建议使用代码块,这样可以充分利用代码块的“闭包”性质。
2.选择或者创建合适的分发队列  
   对于主队列和全局队列系统会默认创建,而且全局队列会有三个不同优先级(高、中、默认),向主线程中提交的代码块会在主线程中执行。

3.(同步、异步方式)提交任务

      可以用异步或同步的方式来提交一个代码块,具体选择什么样的方式可以根据情况而定。除此之外,也可以选择延迟方式提交。


二 队列的使用

1.主队列

      与UI相关的任务应该必须在主线程中来执行,使用dispatch_get_main_queue函数来取得主分发队列的句柄。可以以两种方式向主队列中来提交任务,这两种方式都是异步的,即不管该任务是否执行完毕,都不会阻塞下面任务的执行。

      dispatch_async   执行一个代码块
      dispatch_async_f 执行一个c函数(不常用)

注意:在主线程中不能以(当前提交任务所在的函数在主线程中)dispathch_sync同步的方式提交任务,因为如果此任务比较耗时的话,会阻塞后面的代码(主线程),导致无法响应用户的请求。所有在主线程中向主队列中提前的任务必须是异步的。

void dispatch_async(dispatch_queue_t queue,dispatch_block_t block);
 dispatch_async 有两个参数:
          1.分发队列的句柄   
          2.待执行的代码块,没有返回值和参数
a.创建代码块

void (^TaskOne)(void) = ^(void)
    {
        NSLog(@"Current thread = %@", [NSThread currentThread]);
        NSLog(@"Main thread = %@", [NSThread mainThread]);
       
        [[[UIAlertView alloc] initWithTitle:@"GCD"
                                    message:@"Great Center Dispatcher"
                                   delegate:nil
                          cancelButtonTitle:@"OK"
                          otherButtonTitles:nil, nil] show];
    };


 b.取得分发队列  
    dispatch_queue_t mainQueue = dispatch_get_main_queue();

 c.提交任务   
    dispatch_async(mainQueue, TaskOne);

  


 也可以一步完成:
   dispatch_async( dispatch_get_main_queue(), ^(void)
   {
       
        NSLog(@"Current thread = %@", [NSThread currentThread]);
        NSLog(@"Main thread = %@", [NSThread mainThread]);
      
        [[[UIAlertView alloc] initWithTitle:@"GCD"
                                   message:@"Great Center Dispatcher"
                                  delegate:nil
                         cancelButtonTitle:@"OK"
                         otherButtonTitles:nil, nil] show];
    });

输出结果:

2013-11-08 15:09:27.268 GCDDemo[8567:70b] Current thread = <NSThread: 0x8a166c0>{name = (null), num = 1}

2013-11-08 15:09:27.270 GCDDemo[8567:70b] Main thread = <NSThread: 0x8a166c0>{name = (null), num = 1}

   上面定义的代码块的作用是用来打印当前的线程号和主线程号,通过输出发现他们都为1,说明代码块是在主线程中执行的。

2.全局队列

      下载并显示图片或大量的后台计算操作,可以使用GCD的全局同步队列。可以同步或异步的方式提交我们的任务。同步提交执行并不是意味着程序会阻塞一直到你的代码执行完毕,它只是意味着,同步队列会一直等待直达你的任务执行完毕,才开始执行队列中下一个代码块。

注意:
        a.当我们向全局队列提交一个任务后,程序不会阻塞,因为全局队列中的任务不是在主线程中执行的。但是有个例外,当一个任务以dispatch_sync的方式提交到全局或串行队列的话,IOS可能会在当前线程中(可能在主线程中)去执行,这取决于当前提交代码所在函数的环境。

上面是苹果官方文档的说明,下面例子会详细说明。
 
        b.如果我们以synchronously的方式分别向两个同步队列提交了两个任务,这两个任务是并行的,因为全局队列之间是并行的。

        c.如果我们有A,B两个任务,想当A执行完后B再执行的话,我们可以以同步方式向同一个队列中来提交我们的任务。

dispatch_queue_t dispatch_get_global_queue(
long priority,
unsigned long flags);
   第一个参数是优先级,优先级越高,获得的CPU的时间片也就越多,对列中的任务执行的也就越快。
   第二个参数暂时无意义,保留参数。

- (void) viewDidLoad
{
    void (^printFrom1To100)(void) = ^(void)
    {
        NSUInteger counter = 0;
        for (counter=1;counter<100;  counter++)
        {
            NSLog(@"Counter = %lu- Thread=%@",(unsigned long)counter,[NSThread currentThread]);
        }
     };
    dispatch_queue_t concurrentQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
   
    dispatch_sync(concurrentQueue, printFrom1To100);
    dispatch_sync(concurrentQueue, printFrom1To100);
}
输出结果:

2013-11-08 15:33:01.252 GCDDemo[8649:70b] Counter = 1- Thread=<NSThread: 0x8a80280>{name = (null), num = 1}
2013-11-08 15:33:01.254 GCDDemo[8649:70b] Counter = 2- Thread=<NSThread: 0x8a80280>{name = (null), num = 1}
2013-11-08 15:33:01.255 GCDDemo[8649:70b] Counter = 3- Thread=<NSThread: 0x8a80280>{name = (null), num = 1}
2013-11-08 15:33:01.256 GCDDemo[8649:70b] Counter = 4- Thread=<NSThread: 0x8a80280>{name = (null), num = 1}
2013-11-08 15:33:01.257 GCDDemo[8649:70b] Counter = 5- Thread=<NSThread: 0x8a80280>{name = (null), num = 1}
2013-11-08 15:33:01.258 GCDDemo[8649:70b] Counter = 6- Thread=<NSThread: 0x8a80280>{name = (null), num = 1}
2013-11-08 15:33:01.259 GCDDemo[8649:70b] Counter = 7- Thread=<NSThread: 0x8a80280>{name = (null), num = 1}
2013-11-08 15:33:01.259 GCDDemo[8649:70b] Counter = 8- Thread=<NSThread: 0x8a80280>{name = (null), num = 1}
2013-11-08 15:33:01.260 GCDDemo[8649:70b] Counter = 9- Thread=<NSThread: 0x8a80280>{name = (null), num = 1}
2013-11-08 15:33:01.261 GCDDemo[8649:70b] Counter = 10- Thread=<NSThread: 0x8a80280>{name = (null), num = 1}
………...
2013-11-08 15:33:01.338 GCDDemo[8649:70b] Counter = 1- Thread=<NSThread: 0x8a80280>{name = (null), num = 1}
2013-11-08 15:33:01.339 GCDDemo[8649:70b] Counter = 2- Thread=<NSThread: 0x8a80280>{name = (null), num = 1}
2013-11-08 15:33:01.339 GCDDemo[8649:70b] Counter = 3- Thread=<NSThread: 0x8a80280>{name = (null), num = 1}
2013-11-08 15:33:01.340 GCDDemo[8649:70b] Counter = 4- Thread=<NSThread: 0x8a80280>{name = (null), num = 1}
2013-11-08 15:33:01.340 GCDDemo[8649:70b] Counter = 5- Thread=<NSThread: 0x8a80280>{name = (null), num = 1}
2013-11-08 15:33:01.341 GCDDemo[8649:70b] Counter = 6- Thread=<NSThread: 0x8a80280>{name = (null), num = 1}
2013-11-08 15:33:01.341 GCDDemo[8649:70b] Counter = 7- Thread=<NSThread: 0x8a80280>{name = (null), num = 1}
2013-11-08 15:33:01.342 GCDDemo[8649:70b] Counter = 8- Thread=<NSThread: 0x8a80280>{name = (null), num = 1}
2013-11-08 15:33:01.343 GCDDemo[8649:70b] Counter = 9- Thread=<NSThread: 0x8a80280>{name = (null), num = 1}
2013-11-08 15:33:01.344 GCDDemo[8649:70b] Counter = 10- Thread=<NSThread: 0x8a80280>{name = (null), num = 1}

………..

     上面我们定义了一个代码块,里面执行一个for循环,并打印当前和主线程的线程号。然后我们以同步的方式向全局队列提交了两次,观察结果我们发现:

a.Counter按照顺序1-100输出两遍,说明两个代码块是同步执行的,在前一个执行完后,后面一个才开始执行,也就是说第一个代码块的执行阻塞了全局队列(从而导致第二个代码块阻塞).
b.当前的线程号是1,说明该代码是在主线程中执行

     以上的结果印证了刚才所讲的,“当一个任务以dispatch_sync的方式提交到全局或串行队列的话,IOS可能会在当前线程中(可能在主线程中)去执行”,我们在- (void) viewDidLoad函数中提交的代码块,而这个函数是在主线程中执行的,我们的代码块也在主线程中执行。 
 
下面以异步的方式来提交任务:
- (void) viewDidLoad
{
    void (^printFrom1To100)(void) = ^(void)
    {
        NSUInteger counter = 0;
        for (counter=1;counter<100;  counter++)
        {
            NSLog(@"Counter = %lu- Thread=%@",(unsigned long)counter,[NSThread currentThread]);
        }
     };
    dispatch_queue_t concurrentQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
   
    dispatch_async(concurrentQueue, printFrom1To100);
    dispatch_async(concurrentQueue, printFrom1To100);
}


输出结果:

2013-11-08 15:44:33.663 GCDDemo[8697:1303] Counter = 1- Thread=<NSThread: 0x8b0cdc0>{name = (null), num = 2}
2013-11-08 15:44:33.663 GCDDemo[8697:3207] Counter = 1- Thread=<NSThread: 0x8a39320>{name = (null), num = 3}
2013-11-08 15:44:33.666 GCDDemo[8697:1303] Counter = 2- Thread=<NSThread: 0x8b0cdc0>{name = (null), num = 2}
2013-11-08 15:44:33.666 GCDDemo[8697:3207] Counter = 2- Thread=<NSThread: 0x8a39320>{name = (null), num = 3}
2013-11-08 15:44:33.672 GCDDemo[8697:1303] Counter = 3- Thread=<NSThread: 0x8b0cdc0>{name = (null), num = 2}
2013-11-08 15:44:33.674 GCDDemo[8697:1303] Counter = 4- Thread=<NSThread: 0x8b0cdc0>{name = (null), num = 2}
2013-11-08 15:44:33.674 GCDDemo[8697:1303] Counter = 5- Thread=<NSThread: 0x8b0cdc0>{name = (null), num = 2}
2013-11-08 15:44:33.673 GCDDemo[8697:3207] Counter = 3- Thread=<NSThread: 0x8a39320>{name = (null), num = 3}
2013-11-08 15:44:33.674 GCDDemo[8697:1303] Counter = 6- Thread=<NSThread: 0x8b0cdc0>{name = (null), num = 2}
2013-11-08 15:44:33.674 GCDDemo[8697:3207] Counter = 4- Thread=<NSThread: 0x8a39320>{name = (null), num = 3}
2013-11-08 15:44:33.675 GCDDemo[8697:3207] Counter = 5- Thread=<NSThread: 0x8a39320>{name = (null), num = 3}
2013-11-08 15:44:33.677 GCDDemo[8697:3207] Counter = 6- Thread=<NSThread: 0x8a39320>{name = (null), num = 3}
2013-11-08 15:44:33.677 GCDDemo[8697:3207] Counter = 7- Thread=<NSThread: 0x8a39320>{name = (null), num = 3}
2013-11-08 15:44:33.678 GCDDemo[8697:3207] Counter = 8- Thread=<NSThread: 0x8a39320>{name = (null), num = 3}
2013-11-08 15:44:33.678 GCDDemo[8697:3207] Counter = 9- Thread=<NSThread: 0x8a39320>{name = (null), num = 3}



观察发现:
a.Counter中的数字交错输出,说明两个代码块异步方式并行运行
b.线程号分别为2和3.,说明两个代码块在不同的线程中执行(非主线程)。



     下面来看一个综合例子,下载一个图片 ,当图片下载完后在视图中显示图片,这种场景也是我们在项目中经常要用到的。


大概的代码实现框架如下:

dispatch_queue_t concurrentQueue= dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    dispatch_async(concurrentQueue, ^(void)

    {
        __block UIImage *image = nil;

        dispatch_sync(concurrentQueue, ^(void)
        {
                  /* Download the image here */
        });

        dispatch_sync(dispatch_get_main_queue(), ^(void)
         {
                /* Show the image to the user here on the main queue*/

         }); 

     });


分析:
     我们以异步的方式来提交整个代码块,这样的话代码块的执行不会阻塞下面的代码。在代码块内我们又以同步的方式来执行了两个代码块,所以当执行“ Download the image here”代码块的时候它会阻塞后面的代码的执行,当下载完毕后,我们在主队列中同步的方式来显示图片(对所有涉及UI相关操作必须在主线程中去执行)。



三 自定义队列
  
直接看代码:

首先创建自己的串行队列:

dispatch_queue_t firstSerialQueue = dispatch_queue_create("com.pixolity.GCD.serialQueue1", DISPATCH_QUEUE_SERIAL );


异步方式向队列中提交三个代码块:
    dispatch_async(firstSerialQueue, ^(void)
    {
        NSUInteger counter = 0;
        for (counter = 0;counter < 5;counter++)
        {
            NSLog(@"First iteration, counter = %lu", (unsigned long)counter);
        }
    });
    dispatch_async(firstSerialQueue, ^(void)
    {
        NSUInteger counter = 0;
        for (counter = 0;counter < 5;counter++)
        {
            NSLog(@"Second iteration, counter = %lu", (unsigned long)counter);
        }
    });
    dispatch_async(firstSerialQueue, ^(void)
    {
        NSUInteger counter = 0;
        for (counter = 0;counter < 5;counter++)
        {
            NSLog(@"Third iteration, counter = %lu", (unsigned long)counter);
        }
    });

输出结果:

2013-11-08 17:16:27.721 GCDDemo[9081:2b03] First iteration, counter = 0  Thread=<NSThread: 0x8b91210>{name = (null), num = 2}
2013-11-08 17:16:27.724 GCDDemo[9081:2b03] First iteration, counter = 1  Thread=<NSThread: 0x8b91210>{name = (null), num = 2}
2013-11-08 17:16:27.724 GCDDemo[9081:2b03] First iteration, counter = 2  Thread=<NSThread: 0x8b91210>{name = (null), num = 2}
2013-11-08 17:16:27.725 GCDDemo[9081:2b03] First iteration, counter = 3  Thread=<NSThread: 0x8b91210>{name = (null), num = 2}
2013-11-08 17:16:27.725 GCDDemo[9081:2b03] First iteration, counter = 4  Thread=<NSThread: 0x8b91210>{name = (null), num = 2}
2013-11-08 17:16:27.726 GCDDemo[9081:2b03] Sencond iteration, counter = 0  Thread=<NSThread: 0x8b91210>{name = (null), num = 2}
2013-11-08 17:16:27.726 GCDDemo[9081:2b03] Sencond iteration, counter = 1  Thread=<NSThread: 0x8b91210>{name = (null), num = 2}
2013-11-08 17:16:27.727 GCDDemo[9081:2b03] Sencond iteration, counter = 2  Thread=<NSThread: 0x8b91210>{name = (null), num = 2}
2013-11-08 17:16:27.727 GCDDemo[9081:2b03] Sencond iteration, counter = 3  Thread=<NSThread: 0x8b91210>{name = (null), num = 2}
2013-11-08 17:16:27.727 GCDDemo[9081:2b03] Sencond iteration, counter = 4  Thread=<NSThread: 0x8b91210>{name = (null), num = 2}
2013-11-08 17:16:27.745 GCDDemo[9081:2b03] Third iteration, counter = 0  Thread=<NSThread: 0x8b91210>{name = (null), num = 2}
2013-11-08 17:16:27.745 GCDDemo[9081:2b03] Third iteration, counter = 1  Thread=<NSThread: 0x8b91210>{name = (null), num = 2}
2013-11-08 17:16:27.746 GCDDemo[9081:2b03] Third iteration, counter = 2  Thread=<NSThread: 0x8b91210>{name = (null), num = 2}
2013-11-08 17:16:27.747 GCDDemo[9081:2b03] Third iteration, counter = 3  Thread=<NSThread: 0x8b91210>{name = (null), num = 2}
2013-11-08 17:16:27.751 GCDDemo[9081:2b03] Third iteration, counter = 4  Thread=<NSThread: 0x8b91210>{name = (null), num = 2}



同步的方式提交代码块:

 dispatch_sync(firstSerialQueue, ^(void)
    {
        NSUInteger counter = 0;
        for (counter = 0;counter < 5;counter++)
        {
            NSLog(@"####:sync   counter = %lu  Thread=%@", (unsigned long)counter,[NSThread currentThread]);
        }

    });

2013-11-08 17:19:00.818 GCDDemo[9110:70b] ####:sync   counter = 0  Thread=<NSThread: 0x8a81110>{name = (null), num = 1}
2013-11-08 17:19:00.819 GCDDemo[9110:70b] ####:sync   counter = 1  Thread=<NSThread: 0x8a81110>{name = (null), num = 1}
2013-11-08 17:19:00.819 GCDDemo[9110:70b] ####:sync   counter = 2  Thread=<NSThread: 0x8a81110>{name = (null), num = 1}
2013-11-08 17:19:00.820 GCDDemo[9110:70b] ####:sync   counter = 3  Thread=<NSThread: 0x8a81110>{name = (null), num = 1}

2013-11-08 17:19:00.842 GCDDemo[9110:70b] ####:sync   counter = 4  Thread=<NSThread: 0x8a81110>{name = (null), num = 1}


然后创建自己的同步队列:

dispatch_queue_t 
firstSerialQueue = 
dispatch_queue_create
(
"com.pixolity.GCD.serialQueue1"

DISPATCH_QUEUE_CONCURRENT 
);
    
dispatch_async
(firstSerialQueue, ^(
void
)
    {
        
NSUInteger 
counter = 
0
;
        
for 
(counter = 
0
;counter < 
5
;counter++)
        {
            
NSLog
(
@"First iteration, counter = %lu  Thread=%@"
, (
unsigned 
long
)counter,[
NSThread 
currentThread
]);
        }
    });
    
dispatch_async
(firstSerialQueue, ^(
void
)
    {
        
NSUInteger 
counter = 
0
;
        
for 
(counter = 
0
;counter < 
5
;counter++)
        {
             
NSLog
(
@"Sencond iteration, counter = %lu  Thread=%@"
, (
unsigned 
long
)counter,[
NSThread 
currentThread
]);                    

        }
    });
    dispatch_async(firstSerialQueue, ^(void)
    {
        NSUInteger counter = 0;
        for (counter = 0;counter < 5;counter++)
        {
             NSLog(@"Third iteration, counter = %lu  Thread=%@", (unsigned long)counter,[NSThread currentThread]);
        }
    });

    
输出结果:

2013-11-11 16:52:00.429 GCDDemo[1302:3703] Sencond iteration, counter = 0  Thread=<NSThread: 0x8b93730>{name = (null), num = 3}
2013-11-11 16:52:00.429 GCDDemo[1302:3307] First iteration, counter = 0  Thread=<NSThread: 0x8a5ddf0>{name = (null), num = 2}
2013-11-11 16:52:00.433 GCDDemo[1302:3307] First iteration, counter = 1  Thread=<NSThread: 0x8a5ddf0>{name = (null), num = 2}
2013-11-11 16:52:00.433 GCDDemo[1302:3703] Sencond iteration, counter = 1  Thread=<NSThread: 0x8b93730>{name = (null), num = 3}
2013-11-11 16:52:00.434 GCDDemo[1302:3307] First iteration, counter = 2  Thread=<NSThread: 0x8a5ddf0>{name = (null), num = 2}
2013-11-11 16:52:00.435 GCDDemo[1302:3703] Sencond iteration, counter = 2  Thread=<NSThread: 0x8b93730>{name = (null), num = 3}
2013-11-11 16:52:00.436 GCDDemo[1302:3307] First iteration, counter = 3  Thread=<NSThread: 0x8a5ddf0>{name = (null), num = 2}
2013-11-11 16:52:00.436 GCDDemo[1302:3703] Sencond iteration, counter = 3  Thread=<NSThread: 0x8b93730>{name = (null), num = 3}
2013-11-11 16:52:00.437 GCDDemo[1302:3c03] Third iteration, counter = 0  Thread=<NSThread: 0x8a5a970>{name = (null), num = 4}
2013-11-11 16:52:00.438 GCDDemo[1302:3307] First iteration, counter = 4  Thread=<NSThread: 0x8a5ddf0>{name = (null), num = 2}
2013-11-11 16:52:00.439 GCDDemo[1302:3c03] Third iteration, counter = 1  Thread=<NSThread: 0x8a5a970>{name = (null), num = 4}
2013-11-11 16:52:00.439 GCDDemo[1302:3703] Sencond iteration, counter = 4  Thread=<NSThread: 0x8b93730>{name = (null), num = 3}
2013-11-11 16:52:00.440 GCDDemo[1302:3c03] Third iteration, counter = 2  Thread=<NSThread: 0x8a5a970>{name = (null), num = 4}
2013-11-11 16:52:00.441 GCDDemo[1302:3c03] Third iteration, counter = 3  Thread=<NSThread: 0x8a5a970>{name = (null), num = 4}
2013-11-11 16:52:00.441 GCDDemo[1302:3c03] Third iteration, counter = 4  Thread=<NSThread: 0x8a5a970>{name = (null), num = 4}

同步的方式提交代码块:
 dispatch_sync(firstSerialQueue, ^(void)
    {
        NSUInteger counter = 0;
        for (counter = 0;counter < 5;counter++)
        {
            NSLog(@"####:sync   counter = %lu  Thread=%@", (unsigned long)counter,[NSThread currentThread]);
        }
    });

2013-11-11 17:02:02.221 GCDDemo[1348:70b] ####:sync   counter = 0  Thread=<NSThread: 0x8a406c0>{name = (null), num = 1}
2013-11-11 17:02:02.221 GCDDemo[1348:70b] ####:sync   counter = 1  Thread=<NSThread: 0x8a406c0>{name = (null), num = 1}
2013-11-11 17:02:02.222 GCDDemo[1348:70b] ####:sync   counter = 2  Thread=<NSThread: 0x8a406c0>{name = (null), num = 1}
2013-11-11 17:02:02.222 GCDDemo[1348:70b] ####:sync   counter = 3  Thread=<NSThread: 0x8a406c0>{name = (null), num = 1}

2013-11-11 17:02:02.223 GCDDemo[1348:70b] ####:sync   counter = 4  Thread=<NSThread: 0x8a406c0>{name = (null), num = 1}


观察发现:
1.dispatch_queue_create(const char *label, dispatch_queue_attr_t attr)
    第一个参数是一个c语言形式的字符串
    第二个参数在可以是  DISPATCH_QUEUE_SERIAL (orNULL) 来创建串行队列
                                        DISPATCH_QUEUE_CONCURRENT   来创建同步队列

2.自定义串行队列是严格按照提交FIFO的原则来执行任务,不管你是以何种方式来提交待任务。
3.以同步方式提交的任务都会在当前提交的线程中去执行。例如,在主线程中以同步方式提交的代码块,线程号是1(主线程)。
4.以异步方式提交的任务,它们都不会在当前线程中执行,对于串行队列来说它们都会在同一个线程中去执行,而对于同步队列来说它们分别在不同的线程中去执行。

5.串行队列是系统相关的,为了和别的程序串行队列不冲突,建议使用反转DNS来命名串行队列,以保证唯一性。


6. 自定义串行队列中的任务是串行执行的(不管以何种方式进行提交)。正因为如此,它们可以用来完成同步机制, 有点像传统线程中的mute。


四 延迟提交代码块

直接看代码:

 NSLog(@"here......");
 double delayInSeconds = 5.0;

dispatch_time_t delayInNanoSeconds = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC);
 dispatch_after(delayInNanoSeconds, concurrentQueue, ^(void)
  {
        NSLog(@"delay execute......");

  });

输出结果:

2013-11-08 17:07:00.215 GCDDemo[9036:70b] here......
2013-11-08 17:07:05.252 GCDDemo[9036:1303] delay execute......


观察结果:发现代码块块的执行时间比之前的代码晚了5秒钟void 

dispatch_after(dispatch_time_t when,dispatch_queue_t queue,dispatch_block_t block);

第一个参数用来指定延迟的事件,用dispatch_time函数来构建
第二个参数用来指定队列
第三个参数用来指定要运行的代码块


五  总结

   使用GCD主要把握好每种队列的特点,以及任务提交方式和实际运行线程的对应关系。
   向主队列不管以何种方式提交的代码块总会在主线程中运行,而且为了防止在主线程内提交代码块阻塞主线程,最好以异步的方式来提交代码块;以同步的方式向全局队列和自定义队列提交的代码块,会在当前提交所在线程内执行代码块,不会在另外的线程来执行,以异步的方式提交到全局队列的代码块和自定义队列中的代码块不会阻塞当前线程,会在另外线程中执行;不管以同步还是异步的方式向自定义串行队列提交代码块,都会严格按照提交顺序去执行(one by one);以异步方式向自定义同步队列,会为每个代码块创建一个线程,而以异步方式向自定义串行队列提交的代码块会在同一个线程中执行。
       

IOS GCD 使用 (二)的更多相关文章

  1. 微信连WiFi关注公众号流程更新 解决ios微信扫描二维码不关注就能上网的问题

    前几天鼓捣了一下微信连WiFi功能,设置还蛮简单的,但ytkah发现如果是ios版微信扫描微信连WiFi生成的二维码不用关注公众号就可以直接上网了,而安卓版需要关注公众号才能上网,这样就少了很多ios ...

  2. XMPPFrameWork IOS 开发(二)- xcode配置

    原始地址:XMPPFrameWork IOS 开发(二) 译文地址:   Getting started using XMPPFramework on iOS 介绍 ios上的XMPPFramewor ...

  3. iOS GCD基础篇 - 同步、异步,并发、并行的理解

    1.关于GCD - GCD全称是Grand Central Dispatch  - GCD是苹果公司为多核的并行运算提出的解决方案  - GCD会自动利用更多的CPU内核(比如双核.四核)  - GC ...

  4. 【HELLO WAKA】WAKA iOS客户端 之二 架构设计与实现篇

    上一篇主要做了MAKA APP的需求分析,功能结构分解,架构分析,API分析,API数据结构分析. 这篇主要讲如何从零做iOS应用架构. 全系列 [HELLO WAKA]WAKA iOS客户端 之一 ...

  5. iOS runtime探究(二): 从runtime開始深入理解OC消息转发机制

    你要知道的runtime都在这里 转载请注明出处 http://blog.csdn.net/u014205968/article/details/67639289 本文主要解说runtime相关知识, ...

  6. iOS GCD之dispatch_semaphore(信号量)

    前言 最近在看AFNetworking3.0源码时,注意到在 AFURLSessionManager.m 里面的 tasksForKeyPath: 方法 (L681),dispatch_semapho ...

  7. 苹果IOS内购二次验证返回state为21002的坑

    项目是三四年前的老项目,之前有IOS内购二次验证的接口,貌似很久都没用了,然而最近IOS的妹子说接口用不了,让我看看啥问题.接口流程时很简单的,就是前端IOS在购买成功之后,接收到receipt后进行 ...

  8. iOS GCD 编程小结

    一.简单介绍 1.GCD简介? 全称是Grand Central Dispatch,可译为“牛逼的中枢调度器” 纯C语言,提供了非常多强大的函数 2.GCD优势 GCD是苹果公司为多核的并行运算提出的 ...

  9. 【精】iOS GCD 具体解释

    一.介绍 1.什么是GCD? Grand Central Dispatch.是苹果公司开发的一套多核编程的底层API. GCD首次公布在Mac OS X 10.6,iOS4及以上也可用.GCD存在于l ...

随机推荐

  1. uva 104 Bandwidth

    题意: 给一个图, 将其节点以任一序列排列. 1)计算每个节点距离相邻节点的最大距离 dis[i] 2)计算出当前序列中, 所有节点的dis[i], 并求出最大的dis[i] : max_dis 求最 ...

  2. css中table-layout:fixed 属性的用法

    table-layout:fixed 属性的用法:如果想要一个table固定大小,里面的文字强制换行(尤其是在一长串英文文本,并且中间无空格分隔的情况下),以达到使过长的文字 不撑破表格的目的,一般是 ...

  3. Android-java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()

    章出自:luchg技术交流 http://www.luchg.com 版权所有.本站文章除注明出处外,皆为作者原创文章,可自由引用,但请注明来源,谢谢. Android-java.lang.Runti ...

  4. php的curl获取https加密协议请求返回json数据进行信息获取

    <?php header("Content-type:text/html; charset=utf-8");function getToken($url){        $ ...

  5. Codeforces 258 Div2

    A题,n*m根木棍,相交放置,轮流取走相交的两根,最后谁不能行动,则输掉. min(n,m)&1 为1则先取者赢. B题,给定一个长度为n,且各不相同的数组,问能否通过交换连续一段L....R ...

  6. 李洪强漫谈iOS开发[C语言-024]-表达式与赋值运算符

  7. javaweb学习总结(四十三)——Filter高级开发

    在filter中可以得到代表用户请求和响应的request.response对象,因此在编程中可以使用Decorator(装饰器)模式对request.response对象进行包装,再把包装对象传给目 ...

  8. IEHelper - Internet Explorer Helper Class

    http://www.codeproject.com/Articles/4411/IEHelper-Internet-Explorer-Helper-Class Discussions (81) IE ...

  9. jni.h源码

    /* * jni.h * Java Native Interface. * * Copyright (c) 1996, 1997 * Transvirtual Technologies, Inc. A ...

  10. 函数xdes_find_bit

    使用方法 free = xdes_find_bit(descr, XDES_FREE_BIT, TRUE,hint % FSP_EXTENT_SIZE, mtr); /**************** ...