04 多线程——GCD

作者: CC老师_HelloCoder | 来源:发表于2017-09-04 20:02 被阅读527次

    GCD的简单使用

    什么是GCD

    • 全程是Grand Central Dispatch
    • 纯C语言,提供非常多强大的函数
    • 多核并行运算,不叫多线程,它只是完成了多线程的封装和使用

    GCD的优势

    • GCD是苹果公司为多核的并行运算提出的解决方案;
    • iOS 4.0推出供开发者使用;
    • 使用GCD不关心线程,只要关心队列;线程的调度是由CPU调度,那么我们的CPU是有多核的。如果开发者去调度线程,那是否要考虑CPU的核数了?开发者是不是要考虑适配? 而你使用GCD,则不用动,所以开发者很便利。这就是苹果多它的CPU多核伏笔
    • GCD 会自动利用更多的CPU内核(比如双核、四核)
    • GCD会自动管理线程的生命周期(创建线程、调度任务、销毁线程)
    • 程序员只需要告诉GCD想要执行什么任务,不需要编写任何线程管理代码

    任务和队列

    GCD的2个核心概念

    • 任务:执行什么操作
    • 队列:用来存放任务

    GCD的使用就2个步骤

    • 定制任务(确定想做的事情) 将大象放进冰箱有几步?
    • 将任务添加到队列中

    GCD会自动将==队列==中的==任务==取出,放到对应的==线程==中执行;
    任务的取出遵循对象的==FIFO原则:先进先出,后进后出==

    ==画图分析==
    程序员要做的,将任务添加到队列;队列按照程序员指定的方式,调度任务。执行任务的方法:同步/异步
    同步:一个任务没有结束,就不会执行下一个任务
    异步:不用等待任务执行完毕,就会执行下一个任务

    GCD有一个“线程池”;

    • GCD同步调度任务时,会拿出1根线程,让它执行队列中的任务。当一个任务执行完成后,就会再从队列一个一个的执行;
    • GCD异步调度任务时,首先拿出1根线程,让这个线程去处理一个任务;当任务开始执行,就再从线程池里,再获取一个线程去队列去顺序拿任务执行;指定线程最大并发数;当其中的线程执行任务完毕后,再去队列中按照FIFO原则获取任务;

    图1:同步线程图例

    Snip20170810_1.png
    图2:异步线程图例 Snip20170810_2.png

    ==实例demo 001GCD代码演示==

    在viewController 的touchBegain方法里去调用方法。[self gcdDemo1]

    • 在viewController里,gcdDemo1方法:

    1.创建队列
    2.添加任务到队列中
    3.将任务添加到队列,并且会执行

    写block的方法的窍门:写用函数的思路写出,太函数名前面加一个括号()和 尖尖符号,再在函数体外面的大括号{}前面加一个尖尖符号

    /*
    同步执行方法,这句话不执行完,就不会执行下个任务,同步执行不会开启线程;
    */
    -(void)gcdDemo1
    {
        //1.创建队列
        dispatch_queue_t q = dispatch_get_global_queue(0,0);
        //2.任务添加到队列中
        //2.1定义任务--block
        void (^task)() = ^{
            NSLog(@"%@",[NSThread curresntThread]);
        };
        //2.2 添加任务到队列,并且会执行
        dispatch_sync(q,task);
        
        //合并步骤1,2步,省略写法
        dispatch_sync(q,^{
        NSLog(@"%@",[NSThread currentThread]);
        });
        
    }
    
    • 在viewController里异步执行任务,gcdDemo2方法:

    1.创建队列
    2.添加任务到队列中
    3.将任务添加到异步队列,并且会执行

    异步执行,如果任务没有执行完毕,可以不用等待;异步执行下一个任务。具备开启线程的能力,异步通常又是多线程的代名词!

    /*
    异步任务
    */
    -(void)gcdDemo2
    {
        //1.创建队列
        dispatch_queue_t q = dispatch_get_global_queue(0,0);
        //2.1定义任务--block
        void (^task)() = ^{
            NSLog(@"%@",[NSThread curresntThread]);
        };
        //2.2 添加任务到队列,并且会执行
        dispatch_async(q,task);
    
        
    }
    

    线程间的通讯

    GCD之间的线程通讯

    -(void)gcdDemo3
    {
        //指定任务执行方法 -- 异步
        dispatch_async(dispatch_get_global_queue(0,0),^{
        
        //耗时操作
        NSLog(@"%@",[NSThread currentThread]);
        
        //更新UI
        dispatch_async(dispatch_get_main_Queue(),^{
            NSLog(@"更新UI%@",[NSThread currentThread]);
        });
        
        });
    }
    

    ==修改多线程demo 002--显示网络图片==

    -(void)viewDidLoad
    {
       //代码集中,便于维护
        //利用GCD获取网络图片
        //异步执行
        dispatch_async(dispatch_get_global_queue(0,0),^{
        
        NSURL *url = [NSURL URLWithString:@"http://img3.utuku.china.com/395x0/news/20170629/35381bbe-6e16-4be1-8cf4-4af9107448b7.jpg"];
        NSData *data = [NSData dataWithContentsOfURL:url];
        UIImage *image = [UIImage imageWithData:data];
        
        //更新UI
        dispatch_async(dispatch_get_main_queue(),^{
            self.imageView.image = image;
            [self.imageView sizeToFit];
            self.scrollView.contentSize = image.size;
        });
        
        //block没有循环引用,只是一个代码块,因为它没有作为属性,这里的block用完就释放了。
        });
    }
    

    相关文章

      网友评论

        本文标题: 04 多线程——GCD

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