GCD

队列:

    dispatch_queue_t

    串行队列: 队列中的任务只会顺序执行;

    并行队列: 队列中的任务通常会并发执行.

操作:

    dispatch_async 异步操作,会并发执行,无法确定任务的执行顺序;

    dispatch_sync 同步操作,会依次顺序执行,能够决定任务的执行顺序.   //最好不要用   他是同步先执行完这个,才执行其他,导致页面卡死。

   dispatch_async(dispatch_queue_t queue, dispatch_block_t block); //async表明异步运行,block代表的是你要做的事情,queue则是你把任务交给谁来处理了.

一.Dispatch Queue

Dispatch Queue是一个任务执行队列,可以让你异步或同步地执行多个Block或函数。Dispatch Queue是FIFO的,即先入队的任务总会先执行。目前有三种类型的Dispath Queue:

1.串行队列(Serial dispatch queue)

2.并发队列(Concurrent dispatch queue)

3.主队列(Main dispatch queue)

看例子:

- (IBAction)touchup:(id)sender {
//    dispatch_queue_t myQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);//并行  结果与下列两种相反。  
      dispatch_queue_t myQueue = dispatch_queue_create("com.queue", DISPATCH_QUEUE_CONCURRENT); //并行  结果与下列两种相反。   
 //    dispatch_queue_t myQueue = dispatch_queue_create("com.queue", NULL); //顺序执行 NULL的时候默认是顺序执行 
//    dispatch_queue_t myQueue = dispatch_queue_create("serialQueue", DISPATCH_QUEUE_SERIAL); //顺序执行   顺序执行最好用这两种  不要用sync,会造成页面卡死。
   dispatch_async(myQueue, ^{    
      [NSThread sleepForTimeInterval:6];   
       NSLog(@"[NSThread sleepForTimeInterval:6];");   
   });  
    dispatch_async(myQueue, ^{     
     [NSThread sleepForTimeInterval:3];    
      NSLog(@"[NSThread sleepForTimeInterval:3];");  
    }); 
    dispatch_async(myQueue, ^{    
      [NSThread sleepForTimeInterval:1];    
      NSLog(@"[NSThread sleepForTimeInterval:1];");   
   });
}

总结:串行队列一次只能处理一个任务,可以由用户调用dispatch_queue_create创建。dispatch_queue_create第一个参数是串行队列标识,一般用反转域名的格式表示以防冲突;第二个参数是queue的类型,设为NULL时默认是DISPATCH_QUEUE_SERIAL,将创建串行队列,在必要情况下,你可以将其设置为DISPATCH_QUEUE_CONCURRENT来创建自定义并行队列。

       并行队列可以同时处理多个任务,在不得以的情况下可以用dispatch_queue_create创建,但一般我们都要用系统预定义的并行队列,即全局队列(Global Concurrent Dispatch Queues)。

提示:

    不建议使用不同优先级的队列,因为如果设计不当,可能会出现优先级反转,即低优先级的操作阻塞高优先级的操作.

二.Dispatch Group

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:6];
        NSLog(@"group1 [NSThread sleepForTimeInterval:6];");
    });
    dispatch_group_async(group, queue, ^{
        [NSThread sleepForTimeInterval:3];
        NSLog(@"group2 [NSThread sleepForTimeInterval:3];");
    });
    dispatch_group_async(group, queue, ^{
        [NSThread sleepForTimeInterval:1];
        NSLog(@"group3 [NSThread sleepForTimeInterval:1];");
    });
    dispatch_group_notify(group, dispatch_get_main_queue(), ^{
        NSLog(@"main thread.");
    });
 dispatch_group_async只会监听最终的结果完成后,并通知main queue

三.dispatch_barrier_async

dispatch_barrier_async是在前面的任务执行结束后它才执行,而且它后面的任务等它执行完成之后才会执行,常用于读写的数据同步操作。

- (IBAction)clickBarrier:(id)sender {
//    dispatch_queue_t myQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); //并行执行
     dispatch_queue_t myQueue = dispatch_queue_create("com.queue", DISPATCH_QUEUE_CONCURRENT); //先执行前两项,之后再往下并行执行。
    dispatch_async(myQueue, ^{
        [NSThread sleepForTimeInterval:6];
        NSLog(@"[NSThread sleepForTimeInterval:6];");
    });
    dispatch_async(myQueue, ^{
        [NSThread sleepForTimeInterval:3];
        NSLog(@"[NSThread sleepForTimeInterval:3];");
    });
    dispatch_barrier_async(myQueue, ^{
        NSLog(@"并行执行");
    });
    dispatch_async(myQueue, ^{
        [NSThread sleepForTimeInterval:3];
        NSLog(@"[NSThread sleepForTimeInterval:3];");
    });
    dispatch_async(myQueue, ^{
        [NSThread sleepForTimeInterval:1];
        NSLog(@"[NSThread sleepForTimeInterval:1];");
    });
}
/*打印结果   2015-05-21 14:32:11.898 queueDemo[1870:101851] [NSThread sleepForTimeInterval:3];
            2015-05-21 14:32:14.897 queueDemo[1870:101850] [NSThread sleepForTimeInterval:6];
            2015-05-21 14:32:14.897 queueDemo[1870:101850] 并行执行
            2015-05-21 14:32:15.901 queueDemo[1870:101850] [NSThread sleepForTimeInterval:1];
            2015-05-21 14:32:15.901 queueDemo[1870:101851] [NSThread sleepForTimeInterval:3];  */

总计:dispatch_barrier_async的顺序执行是依赖queue的类型,必需要queue的类型为dispatch_queue_create创建的,而且attr参数值必需是DISPATCH_QUEUE_CONCURRENT类型

四.dispatch_once

 dispatch_once这个函数,它可以保证整个应用程序生命周期中某段代码只被执行一次!多用于对单例的操作。

  1. static dispatch_once_t onceToken;  
        dispatch_once(&onceToken, ^{  
            // code to be executed once  
        });  

五.Dispatch Queue的延迟执行:dispatch_after():

延时操作大都用这个[self performSelector:@selector(btn) withObject:nil afterDelay:1];或者定时

但这两个个方法执行效率低,而且定时时间不准时。所以现在一般都用GCD这个。

  1. double delayInSeconds = 2.0;  
        dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC);  // * NSEC_PER_SEC 这个不能省,否则就是2毫秒了,默认是毫秒,NSEC_PER_SEC表示秒 NSEC_PER_MSEC表示毫秒 
        dispatch_after(popTime, dispatch_get_main_queue(), ^(void){  
            // code to be executed on the main queue after delay  
        });  

     

六.线程队列的挂起与执行

// 挂起队列
dispatch_suspend(queue);
// 恢复队列执行
dispatch_resume(queue);

七.其他

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

dispatch_set_target_queue 可以设置一个dispatch queue的优先级,或者指定一个dispatch source相应的事件处理提交到哪个queue上。

 

附代码:http://i.cnblogs.com/Files.aspx  queueDemo.zip 

 

推荐文章:http://my.oschina.net/aofe/blog/270093

              http://blog.csdn.net/samuelltk/article/details/9452203

       http://www.cnblogs.com/SnailFish/articles/3199863.html

       http://www.cocoachina.com/industry/20131210/7506_2.html

posted @ 2015-05-21 13:49  轻风&星  阅读(278)  评论(0编辑  收藏  举报