GCD备忘

转载请注明出处:http://www.cnblogs.com/idalink/articles/4436276.html

1、总纲

队列和同步异步的组合特征:

总结:

(1)、同步总是不会开辟线程。

(2)、自定义队列虽然开辟线程,但是是串行队列。

(3)、只有开辟线程,才有可能实现并发。

(4)、是否开辟线程不是同步与异步的判断依据,有反例。主队列可以异步,但是没有开辟线程。子线程中同步主队列,队列任务在另外线程中执行,但是却是同步的(这一点第三小节论证)。

2、常见类型与函数

 (1)、dispatch_time_t

指示时间,常用的宏有DISPATCH_TIME_NOW、DISPATCH_TIME_FOREVER

(2)、dispatch_time_t dispatch_time(dispatch_time_t when, int64_t delta);

根据第一个时间参数,往后推次第二个参数delta纳秒时间。量单位有以下宏:

NSEC_PER_USEC、USEC_PER_SEC、NSEC_PER_SEC、NSEC_PER_MSEC。

(相关单词如下:milli[毫]micro[微]nano[纳、毫微])

(3)、dispatch_queue_t dispatch_get_main_queue(void);

获取主队列。

(4)、dispatch_queue_t dispatch_get_global_queue(long identifier, unsigned long flags);

获取全局并发队列,identifier参数指示优先级别,可选:DISPATCH_QUEUE_PRIORITY_LOW、DISPATCH_QUEUE_PRIORITY_DEFAULT、DISPATCH_QUEUE_PRIORITY_HIGH。

(5)、dispatch_queue_t dispatch_queue_create(const char *label, dispatch_queue_attr_t attr);

生成自定义队列,第一个参数标志唯一性,第二个参数暂时无用,穿入NULL即可。

(6)、dispatch_group_t dispatch_group_create(void);

创建一个任务分组。

(7)、void dispatch_group_async(dispatch_group_t group, dispatch_queue_t queue, dispatch_block_t block);

异步在分组中开启任务。

(8)、void dispatch_group_notify(dispatch_group_t group, dispatch_queue_t queue, dispatch_block_t block);

这是个异步函数,分组的任务完成后才开始执行,不管任务是否在同一个线程,同一个队列。

可见一个Demo:

- (void)viewDidLoad {
    [super viewDidLoad];
    
    NSLog(@"线程1---->%@", [NSThread currentThread]);
    
    dispatch_queue_t myqueue = dispatch_queue_create("new_queue1", nil);
    
    dispatch_group_t group = dispatch_group_create();
    
    dispatch_group_async(group, myqueue, ^(){
        
        [NSThread sleepForTimeInterval:3];
        NSLog(@"线程2---->%@", [NSThread currentThread]);
    });
    
    dispatch_group_async(group, dispatch_queue_create("new_queue2", nil), ^(){
        
        [NSThread sleepForTimeInterval:4];
        NSLog(@"线程5---->%@", [NSThread currentThread]);
    });
    
    dispatch_group_notify(group, dispatch_get_main_queue(), ^(){
        
        NSLog(@"线程3---->%@", [NSThread currentThread]);
    });
    NSLog(@"线程4---->%@", [NSThread currentThread]);
}

输出:

2015-04-17 23:24:19.654 test_gcd[1434:73490] 线程1----><NSThread: 0x79952540>{number = 1, name = main}
2015-04-17 23:24:19.655 test_gcd[1434:73490] 线程4----><NSThread: 0x79952540>{number = 1, name = main}
2015-04-17 23:24:22.661 test_gcd[1434:73541] 线程2----><NSThread: 0x7966d0f0>{number = 2, name = (null)}
2015-04-17 23:24:23.658 test_gcd[1434:73540] 线程5----><NSThread: 0x796b7570>{number = 3, name = (null)}
2015-04-17 23:24:23.658 test_gcd[1434:73490] 线程3----><NSThread: 0x79952540>{number = 1, name = main}

 

3、关于队列和同步异步组合的一点说明
第一节已经描述了加载方式和队列的关系,但是并不准确。不开启线程不是说任务在是主队中运行,而是说任务在当前队列中运行。比如在子线程A同步启动一个自定义队列任务,这个任务将会在子线程A中运行,而不是主线程。当然,这种说法依然不够准确。因为无论在什么线程中,任何方式运行主队列任务,都会在主线程中运行。比如在子线程B中异步启动主队列任务,那么这个任务将会在主线程中运行,并且子线程B将会等待主线程的任务。
所以可以修改图表:
 
代码验证:
- (void)viewDidLoad {
    [super viewDidLoad];
    
    NSLog(@"线程1---->%@", [NSThread currentThread]);
    
    dispatch_queue_t globalQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    
    dispatch_async(globalQueue, ^(){
        dispatch_queue_t myqueue = dispatch_queue_create("new_queue2", nil);
        
        NSLog(@"线程2---->%@", [NSThread currentThread]);
        dispatch_async(dispatch_get_main_queue(), ^{
            NSLog(@"线程3---->%@", [NSThread currentThread]);
        });
        NSLog(@"线程4---->%@", [NSThread currentThread]);
        
        dispatch_async(myqueue, ^{
            NSLog(@"线程5---->%@", [NSThread currentThread]);
        });
        NSLog(@"线程6---->%@", [NSThread currentThread]);
    });
}

运行结果:

2015-04-18 22:10:32.891 test_gcd[650:30585] 线程1----><NSThread: 0x7be5b770>{number = 1, name = main}
2015-04-18 22:10:32.892 test_gcd[650:30691] 线程2----><NSThread: 0x7c06f0f0>{number = 2, name = (null)}
2015-04-18 22:10:32.893 test_gcd[650:30691] 线程4----><NSThread: 0x7c06f0f0>{number = 2, name = (null)}
2015-04-18 22:10:32.893 test_gcd[650:30692] 线程5----><NSThread: 0x7be6bfc0>{number = 3, name = (null)}
2015-04-18 22:10:32.893 test_gcd[650:30691] 线程6----><NSThread: 0x7c06f0f0>{number = 2, name = (null)}
2015-04-18 22:10:32.901 test_gcd[650:30585] 线程3----><NSThread: 0x7be5b770>{number = 1, name = main}

 

posted @ 2015-04-18 22:14  Dalink  阅读(233)  评论(0)    收藏  举报