iOS 开发 多线程详解之GCD基本概念

GCD简介

  • 全称是Grand Central Dispatch
  • 纯C语言的,提供了非常多强大的函数.

GCD的优势

  • GCD是苹果公司为多核的并行运算提出的解决方案.
  • GCD会自动利用更多的CPU内核(比如双核、四核)
  • GCD会自动管理线程的生命周期(创建线程、调度任务、销毁线程).
  • 程序员只需要告诉GCD想要执行什么任务,不需要编写任何线程管理代码.

GCD的核心

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

GCD使用的两个步骤

  • 创建任务 : 确定要做的事情
    GCD中的任务是使用BLOCK封装的.
  • 将任务添加到队列中
    GCD会自动将队列中的任务取出,放到对应的线程中执行.
    任务的取出遵循队列的FIFO原则 : 先进先出,后进后出.

GCD的常用代码

1.任务添加到队列分开写

/// 队列+任务
- (void)gcdDemo1
{
    // 全局并发队列
    dispatch_queue_t queue = dispatch_get_global_queue(0, 0);

    // 任务
    void (^task)() = ^ {
        NSLog(@"%@",[NSThread currentThread]);
    };

    // 同步任务
//    dispatch_sync(queue, task);

    // 异步任务 : 每次执行任务的线程不一定是一样的
    dispatch_async(queue, task);

    NSLog(@"end");
}

2.简写

- (void)gcdDemo2
{
    dispatch_async(dispatch_get_global_queue(0, 0), ^{
        NSLog(@"%@",[NSThread currentThread]);
    });
}

3.线程间通信

/// 线程间通信
- (void)gcdDemo3
{
    dispatch_async(dispatch_get_global_queue(0, 0), ^{
        NSLog(@"下载中... %@",[NSThread currentThread]);

        dispatch_async(dispatch_get_main_queue(), ^{
            NSLog(@"下载完成 %@",[NSThread currentThread]);
        });
    });
}

4.使用GCD修改异步下载网络图片的代码

- (void)downloadImage
{
    dispatch_async(dispatch_get_global_queue(0, 0), ^{
        // 获取网络图片地址
        NSURL *url = [NSURL URLWithString:@"http://photocdn.sohu.com/20151209/mp47379110_1449633737507_2_th.png"];
        // 获取网络图片二进制数据
        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 setContentSize:image.size];
        });
    });
}

总结 : 与 NSThread 的对比

  • 所有的代码写在一起的,让代码更加简单,易于阅读和维护
  • NSThread 通过 @selector 指定要执行的方法,代码分散
    GCD 通过 block 指定要执行的代码,代码集中
  • 使用 GCD 不需要管理线程的创建/销毁/复用的过程.程序员不用关心线程的生命周期
  • 如果要开多个线程 NSThread 必须实例化多个线程对象
  • NSThread 靠 NSObject 的分类方法实现的线程间通讯,GCD 靠 block

你可能感兴趣的:(多线程,iOS开发)