• GCD多线程


    1.什么是GCD?

    全称是Grand Central Dispatch

    纯C语言,提供了非常多强大的函数

    2.GCD的优势

    GCD为多核的并行运算提出的解决方案

    GCD会自动利用更多的CPU内核(比如双核、四核)

    GCD会自动管理线程的生命周期(创建线程、调度任务、销毁线程)

    程序员只需要告诉GCD想要执行什么任务,不需要编写任何线程管理代码

    (2)GCD是纯C语言的,因此我们在编写GCD相关代码的时候,面对的函数,而不是方法。
    (3)GCD中的函数大多数都以dispatch开头。

    二、任务和队列

    GCD中有2个核心概念

    (1)任务:执行什么操作

    (2)队列:用来存放任务

    GCD的使用就2个步骤

    (1)定制任务

    (2)确定想做的事情

    将任务添加到队列中,GCD会自动将队列中的任务取出,放到对应的线程中执行

    提示:任务的取出遵循队列的FIFO原则:先进先出,后进后出

    三、执行任务

    1.GCD中有2个用来执行任务的函数

    说明:把右边的参数(任务)提交给左边的参数(队列)进行执行。

    (1)用同步的方式执行任务 dispatch_sync(dispatch_queue_t queue, dispatch_block_t block);

    参数说明:

    queue:队列

    block:任务

    (2)用异步的方式执行任务 dispatch_async(dispatch_queue_t queue, dispatch_block_t block);

    2.同步和异步的区别

    同步:在当前线程中执行

    异步:在另一条线程中执行

     

    1.队列的类型

    GCD的队列可以分为2大类型

    (1)并发队列(Concurrent Dispatch Queue)

    可以让多个任务并发(同时)执行(自动开启多个线程同时执行任务)并发功能只有在异步(dispatch_async)函数下才有效

    (2)串行队列(Serial Dispatch Queue)

    让任务一个接着一个地执行(一个任务执行完毕后,再执行下一个任务)

    2.补充说明

    有4个术语比较容易混淆:同步、异步、并发、串行

    同步和异步决定了要不要开启新的线程

    同步:在当前线程中执行任务,不具备开启新线程的能力

    异步:在新的线程中执行任务,具备开启新线程的能力

    并发和串行决定了任务的执行方式

    并发:多个任务并发(同时)执行

    串行:一个任务执行完毕后,再执行下一个任务

    GCD默认已经提供了全局的并发队列,供整个应用使用,不需要手动创建

    使用dispatch_get_global_queue函数获得全局的并发队列

    dispatch_queue_t dispatch_get_global_queue(dispatch_queue_priority_t priority,unsigned long flags); // 此参数暂时无用,用0即可

    示例:

    这个参数是留给以后用的,暂时用不上,传个0。
    第一个参数为优先级,这里选择默认的。获取一个全局的默认优先级的并发队列。

    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); // 获得全局并发队列

    //下面是方法的具体实现

    #import "ViewController.h"

    @interface ViewController ()

    @end

    @implementation ViewController

    - (void)viewDidLoad {

        [super viewDidLoad];

        UIImageView*imageview=[[UIImageView alloc]initWithFrame:CGRectMake(30, 40, 100, 100)];

        [self.view addSubview:imageview];

        

        

        UIImageView*imageview1=[[UIImageView alloc]initWithFrame:CGRectMake(30, 150, 100, 100)];

        [self.view addSubview:imageview1];

        

        UIImageView*imageview2=[[UIImageView alloc]initWithFrame:CGRectMake(30, 260, 100, 100)];

        [self.view addSubview:imageview2];

        UIImageView*imageview3=[[UIImageView alloc]initWithFrame:CGRectMake(30, 260, 100, 100)];

        [self.view addSubview:imageview3];

        

        UIImageView*imageview4=[[UIImageView alloc]initWithFrame:CGRectMake(30, 260, 100, 100)];

        [self.view addSubview:imageview4];

    //第一种方法

        dispatch_async(dispatch_get_global_queue(0, 0), ^{

           //这里面执行耗时操作

            NSData*data=[NSData dataWithContentsOfURL:[NSURL URLWithString:@"http://www.yooyoo360.com/photo/2009-1-1/20090112132752467.jpg"]];

            UIImage*image=[UIImage imageWithData:data];

        

    dispatch_async(dispatch_get_main_queue(), ^{

        //这里面更新ui

        imageview.image=image;

        

         });

    });

    //第二种方法

    //第二种方法,创建一个组:用于存放耗时操作

        //将操作封装进组,第一个参数代表要存放操作的组名,第二个参数代表操作队列,block执行耗时操作

        dispatch_group_t group=dispatch_group_create();

        __block UIImage*image1,*image2,*image3;

       

        dispatch_group_async(group, dispatch_get_global_queue(0, 0),  ^{

            NSData*data=[NSData dataWithContentsOfURL:[NSURL URLWithString:@"http://pic2.ooopic.com/10/81/58/62bOOOPICce.jpg"]];

            image1=[UIImage imageWithData:data];

        });

        

        dispatch_group_async(group, dispatch_get_global_queue(0, 0),  ^{

            NSData*data=[NSData dataWithContentsOfURL:[NSURL URLWithString:@"http://www.downsc.com/vector_pic/shiliang_iecool/5/3/b_img/14430.jpg"]];

            image2=[UIImage imageWithData:data];

        });

        dispatch_group_async(group, dispatch_get_global_queue(0, 0),  ^{

            NSData*data=[NSData dataWithContentsOfURL:[NSURL URLWithString:@"http://www.downsc.com/vector_pic/shiliang_iecool/5/2/b_img/13788.jpg"]];

            image3=[UIImage imageWithData:data];

        });

        //监听一组操作,第一个参数代表要监听的组名,第二个参数代表一组操作完全结束后跳转到哪个队列,一般跳到主线程(dispatch_get_main_queue),block执行要进行的操作(一般用来更新UI),注意:此方法在组中的所有操作执行完毕后调用

       dispatch_group_notify(group, dispatch_get_main_queue(), ^{

           imageview2.image=image1;

           imageview3.image=image2;

           imageview4.image=image3;

           

       });

  • 相关阅读:
    网页日历显示控件calendar3.1
    切换“使用被动式FTP”
    href="javascript:xxx(this);"和onclick="javascript:xxx(this);"的区别
    CSS布局--上中下布局(上下固定,中间自适应)
    css字体颜色动画
    怎么让jQuery支持swipe事件
    html 5 canvas
    javascript面向对象
    WEB相关存储方式
    angularjs
  • 原文地址:https://www.cnblogs.com/wpw19920808/p/5033387.html
Copyright © 2020-2023  润新知