Grand Central Dispatch 总结

 

//  后台执行:
dispatch_async(dispatch_get_global_queue(0, 0), ^{
     // something
});

 

// 主线程执行:
dispatch_async(dispatch_get_main_queue(), ^{
     // something
});

 

//Once

// 一次性执行:
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
    // code to be executed once
});

 

//Delay

// 延迟 2 秒执行:
double delayInSeconds = 2.0;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC);
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
    // code to be executed on the main queue after delay
});

 

//Custom Queue

//dispatch_queue_t 也可以自己定义,如要要自定义 queue,可以用 dispatch_queue_create 方法,示例如下:
//第二个参数指定queue类型
//DISPATCH_QUEUE_SERIAL(NULL) 串行队列
//DISPATCH_QUEUE_CONCURRENT 并发队列

dispatch_queue_t urls_queue = dispatch_queue_create("www.zhujianting.com", NULL);//NULL表示DISPATCH_QUEUE_SERIAL 串行队列

dispatch_async(urls_queue, ^{
     // your code
});
dispatch_release(urls_queue);

 

//Group 1

//dispatch_group 方法一
//另外,GCD 还有一些高级用法,例如让后台 2 个线程并行执行,
//然后等 2 个线程都结束后,再汇总执行结果。这个可以用 dispatch_group, dispatch_group_async 和 dispatch_group_notify 来实现,示例如下:
dispatch_group_t group = dispatch_group_create();
dispatch_group_async(group, dispatch_get_global_queue(0,0), ^{
     // 并行执行的线程一
});
dispatch_group_async(group, dispatch_get_global_queue(0,0), ^{
     // 并行执行的线程二
});
dispatch_group_notify(group, dispatch_get_global_queue(0,0), ^{
     // 汇总结果
});

 

//Group 2

//dispatch_group 方法二

//创建group
dispatch_group_t imageDownloadGroup = dispatch_group_create();

for (int i = 0; i < count ; i++)
{
    //enter:发起子任务
    dispatch_group_enter(imageDownloadGroup);
    [SDWebImageManager downloadWithURL:theUrl completed:^(BOOL finished)
     {
        //leave:完成子任务
         dispatch_group_leave(imageDownloadGroup);
     }];
}

//子任务全部完成后触发
dispatch_group_notify(imageDownloadGroup,dispatch_get_main_queue(),^
{
    //汇总结果
}

信号量是一个整形值并且具有一个初始计数值,并且支持两个操作:信号通知和等待。当一个信号量被信号通知,其计数会被增加。当一个线程在一个信号量上等待时,线程会被阻塞(如果有必要的话),直至计数器大于零,然后线程会减少这个计数。

dispatch_semaphore_create   创建一个semaphoredispatch_semaphore_signal   发送一个信号dispatch_semaphore_wait    等待信号  

简单的介绍一下这三个函数,第一个函数有一个整形的参数,我们可以理解为信号的总量,dispatch_semaphore_signal是发送一个信号,自然会让信号总量加1,dispatch_semaphore_wait等待信号,当信号总量少于0的时候就会一直等待,否则就可以正常的执行,并让信号总量-1,根据这样的原理,我们便可以快速的创建一个并发控制来同步任务和有限资源访问控制。

//信号量:整数值,最多有10个线程并发    
  dispatch_semaphore_t semaphore = dispatch_semaphore_create(10);       
  for (int i = 0; i < 100; i++)    
  {
        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
            //当前信号量-1           
            dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);                       
            NSLog(@"%d",i+1);                       
            //线程休眠            
            //C           
            //sleep(1);            
            //OC            
            [NSThread sleepForTimeInterval:1];                       
            //当前信号量+1            
            dispatch_semaphore_signal(semaphore);                   
            });
    }

 

//同步操作

/**阻塞线程*/
// 创建一个信号量,值为0    
dispatch_semaphore_t sema = dispatch_semaphore_create(0);    
// 在一个操作结束后发信号,这会使得信号量+1    
ABAddressBookRequestAccessWithCompletion(addressBook, ^(bool granted, CFErrorRef error)
  {           
     dispatch_semaphore_signal(sema);           
  });    
// 一开始执行到这里信号量为0,线程被阻塞,直到上述操作完成使信号量+1,线程解除阻塞
dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);