GCD

关于进程和线程:
进程:进程是指在系统中正在运行的一个应用程序
每个进程之间是独立的.
线程:一个进程要想执行任务,必须得有线程(每一个进程中至少要有一个线程),进程只帮你分配内存.
线程是进程的基本执行单元

注:多线程同时执行,其实是CPU快速地在多线程之间调度,同一时间,CPU只能处理一条线程.

主线程:一个iOS程序运行后,默认会开启一条线程,即”主线程”.或”UI线程”
主线程作用:显示/刷新UI界面 处理UI事件
主线程使用注意:别将比较耗时的操作放到主线程中(下载)

线程同步:
1.实质:为了防止多个线程抢夺同一个资源造成的数据安全问题
2.实现:给代码加一个互斥锁(同步锁)
@synchronized(self){
// 被锁住的代码
}

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

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

使用就2步骤:
定制任务;
将任务添加到队列中(任务取出遵循FIFO,先进先出 后进后出)

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

我们很多时候会混淆一些术语: 同步 异步 串行 并发
同步和异步主要影响:能不能开启新的线程
并发和串行主要影响:任务的执行方式
并发:多个任务并发(同时)执行
串行:一个任务执行完毕后,再执行下一个任务

// dispatch_sync : 同步,不具备开启线程的能力
// dispatch_async : 异步,具备开启线程的能力

// 并发队列 :多个任务可以同时执行
// 串行队列 :一个任务执行完后,再执行下一个任务

队列:存放任务
全局并发队列

dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

自己创建的串行队列

dispatch_queue_t queue = dispatch_queue_create("cn.yj.queue", NULL);

主队列

 dispatch_queue_t queue = dispatch_get_main_queue();

线程间的通信:

  dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        // 执行耗时的异步操作
      
        dispatch_async(dispatch_get_main_queue(), ^{
             //回到主线程,执行UI刷新操作
        });
    });
  • 延时执行
 // 3秒后回到主线程执行block中的代码
    dispatch_queue_t queue = dispatch_get_main_queue();
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC)), queue, ^{
        NSLog(@"------task------%@", [NSThread currentThread]);
    });
    
    // 3秒后自动开启新线程 执行block中的代码
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC)), queue, ^{
        NSLog(@"------task------%@", [NSThread currentThread]);
    });
  • 一次性执行
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        NSLog(@"----once");
       
    });
  • 组队列
    如果我们想同时下载两张图片,再合并,可以利用组队列
  // 1.队列组
    dispatch_group_t group = dispatch_group_create();
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    
    // 2.下载图片1
    __block UIImage *image1 = nil;
    dispatch_group_async(group, queue, ^{
        NSURL *url1 = [NSURL URLWithString:@"http://g.hiphotos.baidu.com/image/pic/item/f2deb48f8c5494ee460de6182ff5e0fe99257e80.jpg"];
        NSData *data1 = [NSData dataWithContentsOfURL:url1];
        image1 = [UIImage imageWithData:data1];
    });
    
    // 3.下载图片2
    __block UIImage *image2 = nil;
    dispatch_group_async(group, queue, ^{
        NSURL *url2 = [NSURL URLWithString:@"http://su.bdimg.com/static/superplus/img/logo_white_ee663702.png"];
        NSData *data2 = [NSData dataWithContentsOfURL:url2];
        image2 = [UIImage imageWithData:data2];
    });
    
    // 4.合并图片 (保证执行完组里面的所有任务之后,再执行notify函数里面的block)
    dispatch_group_notify(group, queue, ^{
        // 开启一个位图上下文
        UIGraphicsBeginImageContextWithOptions(image1.size, NO, 0.0);
        
        // 绘制第1张图片
        CGFloat image1W = image1.size.width;
        CGFloat image1H = image1.size.height;
        [image1 drawInRect:CGRectMake(0, 0, image1W, image1H)];
        
        // 绘制第2张图片
        CGFloat image2W = image2.size.width * 0.5;
        CGFloat image2H = image2.size.height * 0.5;
        CGFloat image2Y = image1H - image2H;
        [image2 drawInRect:CGRectMake(0, image2Y, image2W, image2H)];
        
        // 得到上下文中的图片
        UIImage *fullImage = UIGraphicsGetImageFromCurrentImageContext();
        
        // 结束上下文
        UIGraphicsEndImageContext();
        
        // 5.回到主线程显示图片
        dispatch_async(dispatch_get_main_queue(), ^{
            self.imageView.image = fullImage;
        });
    });
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容