zoukankan      html  css  js  c++  java
  • iOS多线程_06_GCD其它用法

    一、延时执行

    1、iOS常见的延时执行有2种方式

      (1)调用NSObject的方法

    [self performSelector:@selector(run) withObject:nil afterDelay:2.0];
    
    // 2秒后再调用self的run方法

      (2)使用GCD函数

    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
    
        // 2秒后异步执行这里的代码...
    });

      注意:这里异步执行的代码,是放在主队列中执行的 

    2、GCD延时执行

      (1)主队列执行

    1     NSLog(@"延时开始前....");
    2     // 输入dispatch_after
    3     // 从当前时间,延迟2.0秒之后,给主队列添加一个任务(此任务会在主线程上【异步】运行)
    4     dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
    5         NSLog(@"%@", [NSThread currentThread]);
    6     });
    7     NSLog(@"延时设置结束....");

      输出结果:

      延时开始前....

      延时设置结束....

      <NSThread: 0x8d53ea0>{name = (null), num = 1}

       从结果看出,延时操作是在主队列异步运行的,因为 dispatch_after 里边有个 dispatch_get_main_queue参数

      (2)异步任务,开启子线程执行延时

     1     // 1. 队列
     2     dispatch_queue_t q = dispatch_queue_create("myQueue", DISPATCH_QUEUE_CONCURRENT);
     3     
     4     // 2. 异步任务
     5     dispatch_async(q, ^{
     6         NSLog(@"延时开始前.... %@", [NSThread currentThread]);
     7         // 输入dispatch_after
     8         // 从当前时间,延迟2.0秒之后,给主队列添加一个任务(此任务会在主线程上【异步】运行)
     9         dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
    10             NSLog(@"%@", [NSThread currentThread]);
    11         });
    12         NSLog(@"延时设置结束....");
    13     });

      输出结果:

      延时开始前.... <NSThread: 0x8c3f870>{name = (null), num = 2}

      延时设置结束....

      <NSThread: 0x8c23a80>{name = (null), num = 1}

      结果说明,延时操作回到了主线程执行

      (3)延时操作默认在主队列执行的优点:

      调用的方法通常是跟UI有关的,例如提示用户等;

      不了解GCD或者多线程的人,可以直接填空即可。

      (4)dispatch_after 延时操作应用场景

      例如:游戏后台需要做一些随机的事件,需要在某个时间后,调用方法。

      一会儿冒个花,冒个什么的,无意间做了什么操作之后

    二、队列组

      (1)有这么1种需求
      首先:分别异步执行2个耗时的操作
      其次:等2个异步操作都执行完毕后,再回到主线程执行操作
      如果想要快速高效地实现上述需求,可以考虑用队列组
    dispatch_group_t group =  dispatch_group_create();
    
    dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    
        // 执行1个耗时的异步操作
    
    });
    
    dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    
        // 执行1个耗时的异步操作
    
    });
    
    dispatch_group_notify(group, dispatch_get_main_queue(), ^{
    
        // 等前面的异步操作都执行完毕后,回到主线程...
    
    });

      (2)现实例子

      模拟下载多个文件

     1     // 1. 队列
     2     dispatch_queue_t q = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
     3     
     4     // 2. 队列组
     5     dispatch_group_t group = dispatch_group_create();
     6     
     7     // 3. 任务添加到组
     8     dispatch_group_async(group, q, ^{
     9         [NSThread sleepForTimeInterval:5.0];
    10         NSLog(@"下载三国演义中...");
    11     });
    12     dispatch_group_async(group, q, ^{
    13         [NSThread sleepForTimeInterval:2.0];
    14         NSLog(@"下载西游记中...");
    15     });
    16     dispatch_group_async(group, q, ^{
    17         [NSThread sleepForTimeInterval:3.0];
    18         NSLog(@"下载梅中...");
    19     });
    20     
    21     // 所有的书下载完成后通知用户
    22     // 1> 用group统一监听所有的异步任务执行情况,在全部完成后通知
    23     // 2> 注意:所有任务结束后,通常是要通知用户,涉及到UI的交互,因此队列应该使用主队列!
    24     dispatch_group_notify(group, dispatch_get_main_queue(), ^{
    25         // 通常是要通知用户,涉及到UI的交互
    26         NSLog(@"所有书籍都下载完毕! %@", [NSThread currentThread]);
    27     });

      输出结果:

      下载西游记中...

      下载梅中...

      下载三国演义中...

      所有书籍都下载完毕! <NSThread: 0x8c1beb0>{name = (null), num = 1}

      在平常经常用的队列和任务之间加队列组。

      注意:dispatch_group_notify方法的参数为dispatch_get_main_queue,放到主队列通知用户

  • 相关阅读:
    django_视图层_便捷工具
    django_视图层_编写url
    04bootstrap_表单
    人工智能之线性代数
    人工智能之数组操作
    C 获取Linux系统信息
    RPM
    Windows 启动&关闭Hyper-V
    C 指定初始化器
    指针的运算
  • 原文地址:https://www.cnblogs.com/yudigege/p/3932629.html
Copyright © 2011-2022 走看看