GCD函数基本使用

串行(Serial)

任务只能一个个按顺序执行,只能等到上一个任务执行完毕,才能执行当前的任务;

并发 (Concurrent):

任务不按顺序执行,不用等待上一个任务执行完,多个任务是同时执行的;在异步情况下可开启多个线程执行任务;

同步(Synchronous):

  1. 不具备开启新线程的能力;
  2. 任务执行完才返回;
  3. 同步函数: dispatch_sync();

异步 (Asynchronous):

  1. 具备开启新线程的能力;
  2. 提交的任务立即返回;
  3. 异步函数: dispatch_async();

队列 (Dispatch Queue)

苹果为我们提供了串行队列,并行队列,全局队列,主队列!

  • 串行队列
dispatch_queue_t queue = dispatch_queue_create("com.mjz.cn", DISPATCH_QUEUE_SERIAL);
dispatch_queue_t queue = dispatch_queue_create(NULL, NULL);
dispatch_queue_t queue = dispatch_queue_create(0, 0);
  • 并行队列
dispatch_queue_t queue = dispatch_queue_create("com.mjz.cn", DISPATCH_QUEUE_CONCURRENT);
  • 全局队列
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0);
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0);
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0);
  • 主队列
dispatch_queue_t queue = dispatch_get_main_queue();

dispatch_sync

  • 串行队列同步执行
dispatch_queue_t queue = dispatch_queue_create(NULL, NULL);
    for (NSInteger index=0; index<20; index++) {
        dispatch_sync(queue, ^{
            NSLog(@"%ld<-->%@-->%f", index, [NSThread currentThread], [NSThread currentThread].threadPriority);
        });
    }
  1. queue是串行队列;
  2. dispatch_sync是同步执行,不会开启新的线程;

结论:任务按顺序执行,下一个任务只有等待上个任务执行完才能执行!

  • 并行队列同步执行
dispatch_queue_t queue = dispatch_queue_create(NULL, DISPATCH_QUEUE_CONCURRENT);
    for (NSInteger index=0; index<20; index++) {
        dispatch_sync(queue, ^{
            NSLog(@"%ld<-->%@-->%f", index, [NSThread currentThread], [NSThread currentThread].threadPriority);
        });
    }
  1. queue是并行队列;
  2. dispatch_sync是同步执行,不会开启新的线程;

结论:虽然是并行队列,但是dispatch_sync不会开启线程,所以任务还是按顺序执行,跟上面一样的结果!

dispatch_async

  • 串行队列异步执行
dispatch_queue_t queue = dispatch_queue_create(NULL, DISPATCH_QUEUE_SERIAL);
    for (NSInteger index=0; index<20; index++) {
        dispatch_async(queue, ^{
            NSLog(@"%ld<-->%@", index, [NSThread currentThread]);
        });
    }
  1. queue是串行队列;
  2. dispatch_sync是异步执行,开启新的线程;

结论:串行队列任务按顺序执行,但dispatch_async会开启一个新的线程执行!

  • 并行队列异步执行
dispatch_queue_t queue = dispatch_queue_create(NULL, DISPATCH_QUEUE_CONCURRENT);
    for (NSInteger index=0; index<20; index++) {
        dispatch_async(queue, ^{
            NSLog(@"%ld<-->%@", index, [NSThread currentThread]);
        });
    }
  1. queue是并行队列;
  2. dispatch_sync是异步执行,开启新的线程;

结论:并行队列任务同时执行,加上dispatch_async会开启新线程,所以此时会生成多个线程同时执行任务!

一张图总结

Dispatch Group

在串行队列情形下,任务都是按顺序逐一执行;但是到了并行队列的状态下,队列要实现某个任务等到其它队列执行完后才执行就有点难了,这时候我们需要引入了Dispatch Group!

dispatch_group_t group = dispatch_group_create();
    dispatch_queue_t queue = dispatch_queue_create(NULL, DISPATCH_QUEUE_CONCURRENT);
    
    dispatch_group_async(group, queue, ^{
        NSLog(@"11 %@", [NSThread currentThread]);
    });
    dispatch_group_async(group, queue, ^{
        NSLog(@"22 %@", [NSThread currentThread]);
    });
    dispatch_group_async(group, queue, ^{
        NSLog(@"44 %@", [NSThread currentThread]);
    });
    dispatch_group_async(group, queue, ^{
        NSLog(@"55 %@", [NSThread currentThread]);
    });
    dispatch_group_async(group, queue, ^{
        NSLog(@"66 %@", [NSThread currentThread]);
    });
    
    NSLog(@"-------------------------------------");
    dispatch_group_notify(group, queue, ^{
        NSLog(@"33 %@", [NSThread currentThread]);
    });
  • dispatch_group_notify可以轻松地帮助我们实现保证在dispatch_group_notify前的任务执行完成后,dispatch_group_notify中block的任务才能执行,实在方便!
dispatch_group_t group = dispatch_group_create();
    dispatch_queue_t queue = dispatch_queue_create(NULL, DISPATCH_QUEUE_CONCURRENT);

    dispatch_async(queue, ^{
        NSLog(@"11");
    });
    dispatch_async(queue, ^{
        NSLog(@"22");
    });
    dispatch_async(queue, ^{
        NSLog(@"33");
    });
    
    dispatch_group_enter(group);
    dispatch_async(queue, ^{
        
        NSLog(@"66");
        dispatch_group_leave(group);
    });
  • dispatch_group_enter与dispatch_group_leave实现dispatch_group_notify类似效果!!

Dispatch Block

dispatch_queue_t queue = dispatch_queue_create(NULL, DISPATCH_QUEUE_SERIAL);
    dispatch_block_t block = dispatch_block_create(0, ^{
        NSLog(@"mjz");
    });
    dispatch_async(queue, block);
  • dispatch_block_t将任务定义成block,并用队列实现,是队列实现任务的另一种形式!!
dispatch_queue_t queue = dispatch_queue_create(NULL, DISPATCH_QUEUE_SERIAL);
    dispatch_block_t block = dispatch_block_create(0, ^{
        sleep(5.0);
        NSLog(@"mjz");
    });
    dispatch_async(queue, block);

    long result = dispatch_block_wait(block, dispatch_time(DISPATCH_TIME_NOW, NSEC_PER_SEC*5.0));
    if (result==0) {
        NSLog(@"wait finish!!");
    } else {
        NSLog(@"wait error!!");
    }
  • dispatch_block_wait等待block任务执行完毕,会阻塞当前线程,阻塞的时间在wait函数时间值和当前block任务执行时间值取最小的!!
dispatch_queue_t queue = dispatch_queue_create("com.mjz.www", DISPATCH_QUEUE_CONCURRENT);
    dispatch_block_t block = dispatch_block_create(0, ^{
        NSLog(@"block start");
        [NSThread sleepForTimeInterval:1];
        NSLog(@"block1 end");
    });
    dispatch_block_t block2 = dispatch_block_create(0, ^{
        NSLog(@"block2 finish");
    });
    dispatch_async(queue, block);
    dispatch_async(queue, block2);
    dispatch_block_cancel(block2);
  • dispatch_block_cancel取消当前队列执行的任务!!!
dispatch_queue_t queue = dispatch_queue_create(NULL, DISPATCH_QUEUE_CONCURRENT);
    dispatch_apply(6, queue, ^(size_t i) {
        NSLog(@"index: %ld",i);
    });
    NSLog(@"end!!!");
  1. dispatch_apply类似一个for循环,会在指定的dispatch queue中运行block任务n次;
  2. 串行队列则会按顺序执行n次任务;
  3. 并行队列并发执行n次任务,无序!!
dispatch_queue_t queue = dispatch_queue_create(NULL, DISPATCH_QUEUE_CONCURRENT);
    dispatch_async(queue, ^{
        [NSThread sleepForTimeInterval:6];
        NSLog(@"11");
    });
    dispatch_async(queue, ^{
        [NSThread sleepForTimeInterval:2];
        NSLog(@"22");
    });
    dispatch_barrier_async(queue, ^{
        [NSThread sleepForTimeInterval:1];
        NSLog(@"33");
    });
    dispatch_async(queue, ^{
        [NSThread sleepForTimeInterval:1];
        NSLog(@"44");
    });
  • dispatch_barrier_async用于等待前面的任务执行完毕后自己才执行,而它后面的任务需等待它完成之后才执行。

其它

  1. dispatch_queue_create函数的第一个参数指定SERIAL_QUEUE名称,dispatch_queue的名称方便编译器调试;
  2. dispatch_queue_create创建的一个串行队列将生成一个对应的线程执行任务,若是创建多个则将生成多个线程,存在内存安全隐患;
  3. 使用GCD避免死锁问题;
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值