美文网首页
GCD基本介绍

GCD基本介绍

作者: 大美象 | 来源:发表于2017-02-20 16:23 被阅读17次

    与Operation Queues的关系
    Operation Queues 在GCD之前就有了,其中的某些设计原理因Operation Queues而流行,GCD就是基于这些原理构建的。从iOS4与Mac OSX 10.6开始,Operation Queues在底层就是用GCD来实现的。

    GCD是纯C的API,而Operation Queues是Objective-C的对象。

    GCD基本用法
    • 替代同步锁,实现线程安全
      将同步与异步派发结合起来,可以实现与普通加锁机制一样的同步功能,且不会阻塞执行异步派发的线程
      使用同步队列及栅栏块,可以令同步行为更加高效
     _syncQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    
    - (void)setName:(NSString *)name{
        dispatch_barrier_async(_syncQueue, ^{
            _name = name;
        });
    }
    
    - (NSString *)name{
        __block NSString *localString;
        dispatch_async(_syncQueue, ^{
            localString = _name;
        });
        return _name;
    }
    
    - (void)addPhoto:(Photo *)photo
    {
        if (photo) { // 1
            dispatch_barrier_async(self.concurrentPhotoQueue, ^{ // 2 
                [_photosArray addObject:photo]; // 3
                dispatch_async(dispatch_get_main_queue(), ^{ // 4
                    [self postContentAddedNotification]; 
                });
            });
        }
    }
    

    dispatch_after

    延后执行某项任务

    [self performSelector:@selector(doSomething)
                   withObject:nil
                   afterDelay:3];
        
     dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
            [self doSomething];
        });
    
    - (void)showOrHideNavPrompt
    {
        NSUInteger count = [[PhotoManager sharedManager] photos].count;
        double delayInSeconds = 1.0;
        dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC)); // 1 
        dispatch_after(popTime, dispatch_get_main_queue(), ^(void){ // 2 
            if (!count) {
                [self.navigationItem setPrompt:@"Add photos with faces to Googlyify them!"];
            } else {
                [self.navigationItem setPrompt:nil];
            }
        });
    }
    

    dispatch_sync

    dispatch_sync 添加任务到一个队列并等待直到任务完成。

    - (void)viewDidLoad
    {
      [super viewDidLoad];
    dispatch_sync(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
          NSLog(@"First Log");
      });
      NSLog(@"Second Log");
    }
    

    dispatch_async

    dispatch_async 做类似的事情,但不同之处是它不会等待任务的完成,而是立即继续“调用线程”的其它任务。

    //把任务放到主线程执行也有两种方法,但优先使用GCD
    [self performSelectorOnMainThread:@selector(doSomething) withObject:nil waitUntilDone:NO];
    //waitUntilDone= YES dispatch_sync
    dispatch_async(dispatch_get_main_queue(), ^{
            [self doSomething];
     });
    
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{ // 1
            UIImage *overlayImage = [self faceOverlayImageFromImage:_image];
            dispatch_async(dispatch_get_main_queue(), ^{ // 2
                [self fadeInNewImage:overlayImage]; // 3
            });
        });
    
    - (void)viewDidLoad
    {
      [super viewDidLoad];
      dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
          NSLog(@"First Log");
      });
      NSLog(@"Second Log");
    }
    
    

    dispatch_once

    + (instancetype)sharedManager
    {
        static PhotoManager *sharedPhotoManager = nil;
        static dispatch_once_t onceToken;
        dispatch_once(&onceToken, ^{
            sharedPhotoManager = [[PhotoManager alloc] init];
            sharedPhotoManager->_photosArray = [NSMutableArray array];
        });
        return sharedPhotoManager;
    }
    

    Dispatch Groups

    Dispatch Group 会在整个组的任务都完成时通知你。这些任务可以是同步的,也可以是异步的,即便在不同的队列也行。而且在整个组的任务都完成时,Dispatch Group 可以用同步的或者异步的方式通知你。因为要监控的任务在不同队列,那就用一个 dispatch_group_t 的实例来记下这些不同的任务。

    - (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
                Photo *photo = [[Photo alloc] initwithURL:url
                                      withCompletionBlock:^(UIImage *image, NSError *_error) {
                                          if (_error) {
                                              error = _error;
                                          }
                                          dispatch_group_leave(downloadGroup); // 4
                                      }];
    
                [[PhotoManager sharedManager] addPhoto:photo];
            }
            dispatch_group_wait(downloadGroup, DISPATCH_TIME_FOREVER); // 5
            dispatch_async(dispatch_get_main_queue(), ^{ // 6
                if (completionBlock) { // 7
                    completionBlock(error);
                }
            });
        });
    }
    
    - (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);
            }
        });
    }
    
     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:1];
            NSLog(@"group1");
        });
        dispatch_group_async(group, queue, ^{
            [NSThread sleepForTimeInterval:2];
            NSLog(@"group2");
        });
        dispatch_group_async(group, queue, ^{
            [NSThread sleepForTimeInterval:3];
            NSLog(@"group3");
        });
        dispatch_group_notify(group, dispatch_get_main_queue(), ^{
            NSLog(@"updateUi");
        });
        dispatch_release(group);
    
    

    dispatch_apply

    执行某个代码片段N次,
    dispatch_apply(5, globalQ, ^(size_t index) {
        // 执行5次
    });
    

    未完待续...

    https://github.com/nixzhu/dev-blog/blob/master/2014-04-19-grand-central-dispatch-in-depth-part-1.md

    相关文章

      网友评论

          本文标题:GCD基本介绍

          本文链接:https://www.haomeiwen.com/subject/vnykwttx.html