IOS -多线程 - GCD - 初识

时间:2022-01-09 18:37:56

1. 什么是GCD

  a. 全称是Grand Center Dispatch

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

2. GCD的优势

  a. GCD是苹果公司为多核的并行运算提出的解决方案

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

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

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

3. GCD两个核心概念--任务和队列

  任务:要执行的操作(方法) 使用block封装,block 就是一个提前准备好的代码块,在需要的时候执行 

    执行任务的函数

    同步执行:当前指令不完成 , 不会执行下一条指令    dispatch_sync (队列,任务)

    异步执行:当前指令不完成 , 可以执行下一条指令    dispatch_async (队列, 任务)

  队列:用来存放任务的集合

    串行队列:一个接一个的调度任务       dispatch_queue_t q = dispatch_queue_create("js", NULL);

    并发队列:可以同时调度多个任务       dispatch_queue_t q = dispatch_queue_create("js", DISPATCH_QUEUE_CONCURRENT);

    主队列:全局串行队列,由主线程串行调度任务,并且只有一个  dispatch_queue_t q = dispatch_get_main_queue();

    全局队列:没有名称的并发队列        dispatch_queue_t q = dispatch_get_global_queue(0, 0); 

4. GCD使用步骤

  a. 定制任务:确定想做的事情

  b. 将任务添加到队列中,并按照指定的同步或异步方式执行任务

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

    ii. 任务的取出遵循队列的FIFO原则,先进先出 

5.代码示例:

  a.同步执行

//1 队列 此队列是全局的
dispatch_queue_t q = dispatch_get_global_queue(0, 0);
//2 任务
void (^task)() = ^{
  [NSThread sleepForTimeInterval:1];
  NSLog(@"%@",[NSThread currentThread]); 
};
//3 添加到队列,并指定执行方法 
//同步执行,此方法不会开启线程

dispatch_sync(q, task);
NSLog(@"over");

 

  b.异步执行

//异步执行,会开启新线程
//此方法只是把任务添加到队列,然后gcd管理的线程池中有空闲线程就会从队列中取任务执行//1 队列 此队列是全局的
dispatch_queue_t q = dispatch_get_global_queue(0, 0);
//2 任务
void (^task)() = ^{
    [NSThread sleepForTimeInterval:1];
    NSLog(@"%@",[NSThread currentThread]); 
};

dispatch_async(q, task);

NSLog(@"over");

  c.线程间通讯

//此方法只是把任务添加到队列,然后gcd管理的线程池中有空闲线程就会从队列中取任务执行
dispatch_async(dispatch_get_global_queue(0, 0), ^{ //子线程

NSLog(@"%@",[NSThread currentThread]);

//下载图片
NSURL *url = [NSURL URLWithString:@"http://127.0.0.1/pic.jpg"];

NSData *data = [NSData dataWithContentsOfURL:url];

UIImage *image = [UIImage imageWithData:data];

//线程间通讯,给控件赋值,应该在UI线程中 
//在gcd中不直接操作线程,只需要把代码放到主队列中就ok
//主队列中的任务是由主线程来调用
    dispatch_async(dispatch_get_main_queue(), ^{
        self.imageView.image = image;
        [self.imageView sizeToFit];
        self.scrollView.contentSize = image.size;
        self.scrollView.backgroundColor = [UIColor grayColor]; //主线程
        NSLog(@"%@",[NSThread currentThread]); 
    });
});