GCD多线程的使用


1. 什么是 GCD
全称 Grand Central Dispatch ,可译为 中枢调度器 ”, C语言,提供了非常多强大的函数
优点:
GCD 自动管理线程的生命周期(创建线程,调度任务,销毁线程), 自动利用更多的CPU内核(比如双核,四核)
GCD的任务的取出遵循队列的 FIFO 原则:先进先出,后进后出
 容易混淆的术语
 1>. 同步和异步主要影响:能不能开启新的线程
  同步:在当前线程中执行任务,不具备开启新线程的能力
 异步:在新的线程中执行任务,具备开启新线程的能力
 2>. 并发和串行主要影响:任务的执行方式
 
并发:多个任务并发(同时)执行
 串行:一个任务执行完毕后,再执行下一个任务
 GCD 中有 2 个用来执行任务的函数
2.执行的任务:
 1>. 用同步的方式执行任务
 void dispatch_sync(dispatch_queue_t queue, dispatch_block_t block);
 queue:
队列
 block:
任务

 2>.
用异步的方式执行任务
 void dispatch_async(dispatch_queue_t queue, dispatch_block_t block);
队列的类型
 GCD
的队列可以分为 2 大类型
 
并发队列(Concurrent Dispatch Queue
 
可以让多个任务并发(同时)执行(自动开启多个线程同时执行任务)
 并发功能只有在异步(dispatch_async)函数下才有效
 串行队列(Serial Dispatch Queue
 
让任务一个接着一个地执行(一个任务执行完毕后,再执行下一个任务)
 
并发队列 /****   重要   *****/
 GCD 默认已经提供了全局的并发队列,供整个应用使用,不需要手动创建
 
使用

 dispatch_queue_t dispatch_get_global_queue(long identifier, unsigned long flags);
 
返回值 dispatch_queue_t 队列
 
参数 long identifier 全局并发队列优先级
 参数 unsigned long flags=0 此参数暂时无用,用0即可
 // 全局并发队列的优先级
 #define DISPATCH_QUEUE_PRIORITY_HIGH 2

 #define DISPATCH_QUEUE_PRIORITY_DEFAULT 0
默认(中)
 #define DISPATCH_QUEUE_PRIORITY_LOW (-2)
 #define DISPATCH_QUEUE_PRIORITY_BACKGROUND INT16_MIN 后台


线程间的使用:
//异步并发执行:

3.  GCD 延迟执行
例如:
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
   
NSLog(@"----touchesBegan");
#if 0
    //错误的做法 缺点:卡住当前线程
    [NSThread sleepForTimeInterval:
3
];
    NSLog(
@"---下载图片");
    NSLog(
@"----downloadfinished");
#endif
   
#if 0
2> 1. 调用 NSObject 的方法
    //一旦定制好 延迟任务后 不会卡住当前线程, 3秒后回到主线程中执行download方法不会卡住当前线程
    [self performSelector:@selector(download) withObject:nil afterDelay:3.0f];
    NSLog(
@"----downloadfinished");
#endif
   
#if 0
    //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(
@"----下载图片 %@"
,[NSThread currentThread]);
    });
    NSLog(
@"----downloadfinished");
#endif

    //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(@"----下载图片 %@",[NSThread currentThread]);
    });
   
NSLog(@"----downloadfinished"
);
}
- (void)download
{
   
NSLog(@"---下载图片 %@",[NSThread currentThread]);
}


4. 一次性代码
- (void)download
{
   
//一次性代码 使用dispatch_once_t函数能保证某段代码在程序运行过程中只被执行1次(block中的代码默认是线程安全的)
   
//永远只执行一次,从函数的开始到结束
   
static dispatch_once_t onceToken;
   
dispatch_once(&onceToken, ^{
       
NSLog(@"下载图片"
);
    });
//    if (self.hasExcuted) return;
//    NSLog(@" 下载图片 ");
//    self.hasExcuted = YES;
}

五:  GCD 队列组:

1.队列组可以解决如下需求
首先:分别异步执行2个耗时操作
其次:等2个异步操作都执行完毕后,再回到主线程执行操作
//1. 队列组
   
dispatch_group_t group = dispatch_group_create();
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    dispatch_group_async(<#dispatch_group_t group#>, <#dispatch_queue_t queue#>, ^{
       
//下载图片等操作
       
    });
   
//(保证组里面所有的任务都执行完成后 再执行notify函数里面的block
    dispatch_group_notify(<#dispatch_group_t group#>, <#dispatch_queue_t queue#>, ^{
       
//执行图片合并等操作
        ……..
       
//回到主线程显示

        dispatch_async(dispatch_get_main_queue(), ^{
           
//显示内容等操作
        });
    });
    
要求:
//例如:
//1 分别下载两张图片:大图片 logo
//2 合并两张图片
//3 显示到一个 imageView

// 百度 logo http://img.baidu.com/img/baike/logo-baike.png


此处还可以用异步并发队列来实现此功能
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值