2分钟学会GCD

来源:互联网 发布:淘宝竞争情报有用吗 编辑:程序博客网 时间:2024/04/27 14:03

哈哈 骗你的了 怎么可能两分钟真正的学会GCD,但是我会用最简短的语言说明什么是GCD,不会耽误你太多时间。

先说说基本概念,再说说常用API

gcd是一个C语言的底层库代码,使用了高并发模型进行处理,而不是简单的锁和线程,使用GCD能优化你的程序性能,推迟大运算,调用多处理器,还能提供一些更完善的函数接口,例如单例。

GCD分两种形式的调用

同步调用:等待任务结束,线程阻塞dispatch_sync

异步调用:直接返回,线程不阻塞dispatch_async

GCD又分了三种队列

主队列:串行队列,在主线程执行,任务一个个挨着执行

4个不同优先级的全局调度队列:并行队列,同时执行任务的队列

自创队列:串行和并行自己选,这个好处是可控,可追溯

GCD的一些注意事项

  1. 很多时候是两个GCD嵌套使用的,比如说先处理数据再回调修改UI,或者先处理数据,再回调某些处理方法
  2. 可以使用dispatch_after来延迟执行方法,可以理解为延迟的dispatch_async
  3. 使用dispatch_once来处里某些线程安全的
  4. dispatch_barrier可以用来作为读写锁,保证写入的时候没有任何读取操作
  5. Dispatch Group 会在整个组的任务都完成时通知你
说道 Group 这个倒是需要详细的说说,有时候使用它能帮助你解决很多不好处理的麻烦
他有两种实现方式,第一种是dispatch_group_wait,它会阻塞当前线程,类似一个线程池,进入一个计数+1,完成-1,也就是说只有在所有进入的任务全部完成,计数为0的时候才会结束此group,直接上代码
- (void)downloadPhotosWithCompletionBlock:(BatchPhotoDownloadingCompletionBlock)completionBlock{    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{ // 1在一个异步队列中调用,不阻塞主线程        __block NSError *error;        dispatch_group_t downloadGroup = dispatch_group_create(); // 2创建组        for (NSInteger i = 0; i < 3; i++) {            NSURL *url;            switch (i) {                case 0:                    url = [NSURL URLWithString:kOverlyAttachedGirlfriendURLString];                    break;                case 1:                    url = [NSURL URLWithString:kSuccessKidURLString];                    break;                case 2:                    url = [NSURL URLWithString:kLotsOfFacesURLString];                    break;                default:                    break;            }            dispatch_group_enter(downloadGroup); // 3进组组 +1            Photo *photo = [[Photo alloc] initwithURL:url                                  withCompletionBlock:^(UIImage *image, NSError *_error) {                                      if (_error) {                                          error = _error;                                      }                                      dispatch_group_leave(downloadGroup); // 4 退出组 -1                                  }];            [[PhotoManager sharedManager] addPhoto:photo];        }        dispatch_group_wait(downloadGroup, DISPATCH_TIME_FOREVER); // 5等待完成,设置超时        dispatch_async(dispatch_get_main_queue(), ^{ // 6 完成后回调            if (completionBlock) { // 7                completionBlock(error);            }        });    });}
第二种dipath_group_notify其实和第一种一样,唯一的优点就是不需要先起一个异步队列了,它不会阻塞线程
直接上代码
- (void)downloadPhotosWithCompletionBlock:(BatchPhotoDownloadingCompletionBlock)completionBlock{    // 1    __block NSError *error;    dispatch_group_t downloadGroup = dispatch_group_create();     for (NSInteger i = 0; i < 3; i++) {        NSURL *url;        switch (i) {            case 0:                url = [NSURL URLWithString:kOverlyAttachedGirlfriendURLString];                break;            case 1:                url = [NSURL URLWithString:kSuccessKidURLString];                break;            case 2:                url = [NSURL URLWithString:kLotsOfFacesURLString];                break;            default:                break;        }        dispatch_group_enter(downloadGroup); // 2        Photo *photo = [[Photo alloc] initwithURL:url                              withCompletionBlock:^(UIImage *image, NSError *_error) {                                  if (_error) {                                      error = _error;                                  }                                  dispatch_group_leave(downloadGroup); // 3                              }];        [[PhotoManager sharedManager] addPhoto:photo];    }    dispatch_group_notify(downloadGroup, dispatch_get_main_queue(), ^{ // 4        if (completionBlock) {            completionBlock(error);        }    });}
最后再说点其他的,上面的for循环其实也可以用 dispath_apply 来代替的

我的两分钟教学就到此为止了,其实完全是照抄了大神的博客,然后就是缩缩缩,要想看大神

http://www.raywenderlich.com/63338/grand-central-dispatch-in-depth-part-1
http://www.raywenderlich.com/63338/grand-central-dispatch-in-depth-part-2



0 0
原创粉丝点击