本篇文章中我们主要讲解GCD中的函数。
GCD
GCD
是Grand Central Dispatch
的简称,纯c语言
,提供了非常多强大的函数,将任务添加到队列,并且指定执行任务的函数
。
函数
- 1,
GCD中的函数
使用block
封装,任务的block没有参数也没有返回值。 - 2,异步函数
dispatch_async
: 不用等待当前语句执行完毕,就可以执行下一条语句,会开启线程执行block的任务。 - 3,同步函数
dispatch_sync
,必须等待当前语句执行完毕,才会执行下一条语句,不会开启线程
,在当前执行block的任务。
函数与队列
同步函数串行队列
- 1,
不会开启线程
,在当前线程执行任务。 - 2,任务串行执行,任务一个接着一个。
- 3,会产生堵塞。
同步函数并发队列
- 1,
不会开启线程
,在当前线程执行任务。 - 2,任务一个接着一个执行。
异步函数串行队列
- 1,
开启一条新线程
。 - 2,任务一个接着一个执行。
异步函数并发对列
- 1,
开启线程
,在当前线程执行任务。 - 2,
任务异步执行,没有顺序
,与CPU调度有关。
dispatch_sync
dispatch_sync
函数,如果 dispatch_sync()
的目标queue
为当前queue
,且 当前queue为串行队列
时,会发生死锁
(并行queue并不会)。
下面我们通过下面的几个函数示例来验证一下:
- (void)viewDidLoad {
[super viewDidLoad];
[self mainSyncTest];
}
- (void)mainSyncTest{
NSLog(@"0");
dispatch_sync(dispatch_get_main_queue(), ^{
NSLog(@"1");
});
NSLog(@"2");
}
- 在
主线程
中调用dispatch_sync
函数,且目标queue
,为主线程
,住线程是一个串行队列
,所以会造成死锁
。
- (void)test1{
dispatch_queue_t queue = dispatch_queue_create("LY", NULL);
NSLog(@"1");
// 异步函数
dispatch_async(queue, ^{
NSLog(@"2");
// 同步
dispatch_sync(queue, ^{
NSLog(@"3");
});
NSLog(@"4");
});
NSLog(@"5");
}
- (void)test2 {
dispatch_queue_t queue1 = dispatch_queue_create("LY", NULL); // 串行队列
dispatch_queue_t queue2 = dispatch_queue_create("Nice", NULL); // 串行队列
NSLog(@"1");
// 异步函数
dispatch_async(queue1, ^{
NSLog(@"2");
// 同步
dispatch_sync(queue2, ^{
NSLog(@"3");
});
NSLog(@"4");
});
NSLog(@"5");
}
- test1 函数,
目标queue
是当前queue
,并且都为串行队列,会导致死锁
。 - test2 函数,
dispatch_sync
的当前queue
为queue1
,目标queue
为queue2
,因为queue1和queue2
不是同一个队列,不会造成死锁。
-(void) test3 {
dispatch_queue_t queue = dispatch_queue_create("LY", DISPATCH_QUEUE_CONCURRENT);
NSLog(@"1");
dispatch_async(queue, ^{
NSLog(@"2");
dispatch_sync(queue, ^{
NSLog(@"3");
});
NSLog(@"4");
});
NSLog(@"5");
}
- test3 函数,
dispatch_sync
函数的当前queue
和目标queue
为同一个queue
。但该队列为并发队列
,并不会造成死锁。
最后,奉上本文的代码示例 GCD