GCD理解(二)
来源:互联网 发布:怎么发送淘宝店铺链接 编辑:程序博客网 时间:2024/06/05 17:33
串行
串行队列包括用户队列、主线程队列
-串行同步
//串行同步 dispatch_queue_t queue = dispatch_queue_create("serial_sync", nil); dispatch_sync(queue, ^{ sleep(1); NSLog(@"sync serial name '%@' in a process",queue); }); NSLog(@"sync serial sync process end");
- 串行异步
//串行异步 dispatch_queue_t asynQueue = dispatch_queue_create("serial_async", nil); dispatch_async(asynQueue, ^{ sleep(1); NSLog(@"async serial name '%s' in a process",dispatch_queue_get_label(asynQueue)); }); NSLog(@"async serial sync process end");
并行
//并发队列 :Concurrent Queues dispatch_queue_t aQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); dispatch_queue_t aHQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0); dispatch_queue_t aLQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0);
Demo-并行队列
- (void)testConcurrentQueue{ dispatch_queue_t concurrentQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); //记时开始 NSDate *startTime = [NSDate date]; //两个同步的任务用一个异步的包起来,提交到并行队列里去,即可实现同步的方式. //加入队列 dispatch_async(concurrentQueue, ^{ NSLog(@"并行同步 start at %@",startTime); __block UIImage *image = nil; //1.先去下载图片 dispatch_sync(concurrentQueue, ^{ NSString *urlAsString = @"https://www.baidu.com/img/bdlogo.png"; NSURL *url = [NSURL URLWithString:urlAsString]; NSError *downloadError = nil; NSData *imageData = [NSURLConnection sendSynchronousRequest:[NSURLRequest requestWithURL:url] returningResponse:nil error:&downloadError]; if (downloadError == nil && imageData != nil) { image = [UIImage imageWithData:imageData]; } else if(downloadError != nil){ NSLog(@"error happened = %@", downloadError); } else{ NSLog(@"No data download"); } }); //2.在主线程展示到界面里 __block typeof (self)weakSelf = self; dispatch_sync(dispatch_get_main_queue(), ^{ if (image != nil) { [weakSelf.imageView setImage:image]; NSDate *endTime = [NSDate date]; NSLog(@"并行同步 completed in %f time", [endTime timeIntervalSinceDate:startTime]); } else{ NSLog(@"image isn't downloaded, nothing to display"); } }); });}
主队列
//主队列 dispatch_queue_t mainQueue = dispatch_get_main_queue();
分组
对分组的理解
将几个有关联的任务组合起来,然后提供一个知道这个group结束的点,接着再执行其他任务。
dispatch_notify()提供了一个知道group什么时候结束的点. 也可以使用dispatch_wait()去阻塞.见demo
Demo-简单分组
//获取并发队列:加上sleep可以更好的理解 dispatch_queue_t aQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); //创建2个queue group: a 负责任务123,b负责456 dispatch_group_t aGroup = dispatch_group_create(); dispatch_group_t bGroup = dispatch_group_create(); dispatch_group_async(aGroup, aQueue, ^{ NSLog(@"task 1 start"); sleep(3); NSLog(@"task 1 : queue name is %s ,group name is %s",dispatch_queue_get_label(aQueue),dispatch_queue_get_label(aQueue)); }); dispatch_group_async(aGroup, aQueue, ^{ NSLog(@"task 2 start"); sleep(2); NSLog(@"task 2 : queue name is %s ,group name is %s",dispatch_queue_get_label(aQueue),dispatch_queue_get_label(aQueue)); }); dispatch_group_async(aGroup, aQueue, ^{ NSLog(@"task 3 start"); sleep(10); NSLog(@"task 3 : queue name is %s ,group name is %s",dispatch_queue_get_label(aQueue),dispatch_queue_get_label(aQueue)); }); NSLog(@"wait task 1,2,3."); //等待组内任务全部完成 dispatch_group_wait(aGroup, DISPATCH_TIME_FOREVER); NSLog(@"task 1,2,3 finished."); //任务4 dispatch_group_async(bGroup, aQueue, ^{ NSLog(@"task 4."); }); //任务5 dispatch_group_async(bGroup, aQueue, ^{ NSLog(@"task 5."); }); //任务6 dispatch_group_async(bGroup, aQueue, ^{ NSLog(@"task 6."); }); NSLog(@"wait task 4,5,6."); //等待组内任务全部完成 dispatch_group_wait(bGroup, DISPATCH_TIME_FOREVER); NSLog(@"task 4,5,6 finished.");
分组的例子:下载图片并展示
dispatch_group_t group = dispatch_group_create(); dispatch_queue_t queue = dispatch_get_global_queue(0, 0); NSDate *startTime = [NSDate date]; __block UIImage *image = nil; dispatch_group_async(group, queue, ^{ NSLog(@"分组同步 start in %@",startTime); //1.先去网上下载图片 NSString *urlAsString = @"http://s0.hao123img.com/res/img/logo/logonew1.png"; NSURL *url = [NSURL URLWithString:urlAsString]; NSError *downloadError = nil; NSData *imageData = [NSURLConnection sendSynchronousRequest:[NSURLRequest requestWithURL:url] returningResponse:nil error:&downloadError]; if (downloadError == nil && imageData != nil) { image = [UIImage imageWithData:imageData]; } else if(downloadError != nil){ NSLog(@"error happened = %@", downloadError); } else{ NSLog(@"No data download"); } }); __block typeof (self)weakSelf = self; // 2.等下载好了再在刷新主线程 dispatch_group_notify(group, queue, ^{ //在主线程展示到界面里 dispatch_async(dispatch_get_main_queue(), ^{ if (image != nil) { [weakSelf.imageView setImage:image]; NSDate *endTime = [NSDate date]; NSLog(@"分组同步 end at %@,completed in %f time",endTime, [endTime timeIntervalSinceDate:startTime]); } else{ NSLog(@"image isn't downloaded, nothing to display"); } }); });
注
- concurrent queues和main queue都是由系统生成而且 dispatch_suspend, dispatch_resume, dispatch_set_context这些函数对他们无效。
- GCD下的dispatch_queue队列不管是并发队列都是FIFO队列,,都会按照提交到队列的顺序执行.
- 提交到主线程队列的时候,要慎用dispatch_sync方法,有可能造成死锁. 因为主线程队列是串行队列,要等队列里的任务一个一个执行.所以提交一个任务到队列,如果用同步方法就会阻塞住主线程,而主线程又要等主线程队列里的任务都执行完才能执行刚提交的,所以主线程队列里还有其他的任务的话,但他已经被阻塞住了,没法先完成队列里的其他任务,即,最后一个任务也没机会执行到,于是造成死锁.
- 提交到串行队列可以用同步方式,也可以用异步方式.
- 采用并行队列的时候,可以采用同步的方式把任务提交到队列里去,即可以实现同步的方式(两个同步的任务用一个异步的包起来,提交到并行队列里去,即可实现同步的方式.)
如有不对,请指正。谢谢
0 0
- GCD 深入理解二
- GCD理解(二)
- gcd学习理解(二)
- GCD 深入理解(二)
- GCD 深入理解(二)
- GCD 深入理解(二)
- GCD 深入理解(二)
- GCD 深入理解(二)
- GCD 深入理解(二)
- GCD深入理解(二)
- GCD 深入理解(二)
- GCD 深入理解(二)
- GCD 深入理解(二)
- GCD 深入理解(二)
- GCD 深入理解(二)
- GCD深入理解(二)
- GCD 深入理解(二)
- GCD 深入理解(二)
- JXLS-----JXLS读取Excel实例
- 第一周周三
- hdoj 1213 How Many Tables 【并查集】
- 机房收费系统——再回首
- 查找文件中的某个内容出现的次数
- GCD理解(二)
- hdu杭电2120 Ice_cream's world I【并查集】
- Linux基本命令
- Swift中元组(Tuples),结构体(Struct),枚举(Enums)之间的区别
- Android动态改变GridView的值【安卓进化二十二】
- solr+solrJ facet.pivot 用法实例
- 取逗号之间的字符
- 使用AFNetWorking 上传图片
- iOS 获取设备唯一标识