GCD常用方法之总结

参考文章:http://www.jianshu.com/p/2d57c72016c6

1 开启多线程的方法

  • Thread:基于C语言,基本已经不用,需要程序猿开启和管理线程的声明周期
  • NSThread:基于Thread的封装,oc语言,需要程序猿开启和管理线程的声明周期
  • GCD:旨在替代NSThread,基于C语言,功能强大,自动管理线程的生命周期
  • NSOperation:GCD的封装,基于oc语言,自动管理线程的生命周期。

2 GCD的核心概念

  • 任务:
    同步执行(sync):只能在当前线程中执行任务,不具备开启新线程的能力
    异步执行(async):可以在新的线程中执行任务,具备开启新线程的能力
  • 队列:
    并发队列(Concurrent Dispatch Queue):可以让多个任务并发(同时)执行(自动开启多个线程同时执行任务),并发功能只有在异步(dispatch_async)函数下才有效
    串行队列(Serial Dispatch Queue):让任务一个接着一个地执行(一个任务执行完毕后,再执行下一个任务)

3 GCD的基本使用

3.1 线程间通信(子线程下载数据,主线程刷新UI)

//1.开子线程下载图片,异步函数,全局并发队列
    dispatch_async(dispatch_get_global_queue(0, 0), ^{
       
        //2.下载图片
        //2.1 确定URL
        NSURL *url = [NSURL URLWithString:@"https://image.baidu.com"];
        
        //2.2 下载二进制数据
        NSData *data = [NSData dataWithContentsOfURL:url];
        
        //2.3 转换为图片
        UIImage *image = [UIImage imageWithData:data];
        
        // 子线程
        NSLog(@"download---%@",[NSThread currentThread]);
        
        //3.回到主线程刷新UI
        // dispatch_async(dispatch_get_main_queue(), ^{
         dispatch_sync(dispatch_get_main_queue(), ^{
        
            self.imageView.image = image;
             
             // 主线程
              NSLog(@"UI---%@",[NSThread currentThread]);
        });
    });

3.2 GCD常用函数

(1)时间延迟

   //1.NStimer
    // NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:2.0 target:self selector:@selector(task) userInfo:nil repeats:YES];
    
    //2.afterDelay
    //[self performSelector:@selector(task) withObject:nil afterDelay:2.0];
    
    //3.GCD
    //dispatch_queue_t queue = dispatch_get_main_queue();
    dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)),queue , ^{
        
        NSLog(@"---GCD----%@",[NSThread currentThread]);
    });

(2)一次性代码(注意:不能写在懒加载中)

 static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        NSLog(@"---once----");
    });

(3)栅栏函数

 //栅栏函数:控制并发队列中任务的执行顺序
    dispatch_barrier_async(queue, ^{
        NSLog(@"+++++++++++++++++++++++++++");
    });

(4) 快速迭代函数

//1.获得并发队列
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    
    //2.快速迭代
    /*
     第一个参数:要迭代的次数
     第二个参数:队列,并发队列
     第三个参数:block 封装任务
     */
    dispatch_apply(10, queue, ^(size_t index) {
        NSLog(@"%zd----%@",index,[NSThread currentThread]);
    });

(5) 队列组

//需求:
/*
 下载图片1
 下载图片2
 当下载完成之后合成
 */
-(void)combie
{
    //0.创建队列组
    dispatch_group_t group = dispatch_group_create();
    
    //1.并发队列
    dispatch_queue_t queue  = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
        
    //2.异步函数,下载图片1
    dispatch_group_async(group, queue, ^{
       
        NSLog(@"DOWNLOAD1---%@",[NSThread currentThread]);
        //2.1 确定URL
        NSURL *url = [NSURL URLWithString:@"http://imgsrc.baidu.com/forum/pic/item/c69ae2003af33a87ecb1c796c65c10385143b585.jpg"];
        
        //2.2 下载二进制数据
        NSData *imageData = [NSData dataWithContentsOfURL:url];
        
        //2.3 转换为图片
        self.image1 = [UIImage imageWithData:imageData];
    });
    
    //3.异步函数,下载图片2
    dispatch_group_async(group, queue, ^{
        
          NSLog(@"DOWNLOAD2---%@",[NSThread currentThread]);
        //3.1 确定URL
        NSURL *url = [NSURL URLWithString:@"http://s6.sinaimg.cn/middle/6753066ftc67bdde1ca25&690"];
        
        //3.2 下载二进制数据
        NSData *imageData = [NSData dataWithContentsOfURL:url];
        
        //3.3 转换为图片
       self.image2 = [UIImage imageWithData:imageData];
    });

 dispatch_group_notify(group, dispatch_get_main_queue(), ^{
        
        NSLog(@"COMBIE---%@",[NSThread currentThread]);
        
        //4.1 开启图形上下文
        UIGraphicsBeginImageContext(CGSizeMake(200, 200));
        
        //4.2 画图1
        [self.image1 drawInRect:CGRectMake(0, 0, 200, 100)];
        
        //4.3 画图2
        [self.image2 drawInRect:CGRectMake(0, 100, 200, 100)];
        
        //4.4 得到图片
        UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
        
        //4.5 关闭图形上下文
        UIGraphicsEndImageContext();
        
        //5.线程间通信,回到主线程属性UI
       // dispatch_async(dispatch_get_main_queue(), ^{
            self.imageView.image = image;
            NSLog(@"UI---%@",[NSThread currentThread]);
        //});
    });

你可能感兴趣的:(GCD常用方法之总结)