【iOS】多线程GCD

GCDGrand Central Dispatch : 牛逼的中枢调度器。苹果自带,纯C语言实现,提供了非常多且强大的函数,它可以提高代码的执行效率与多核的利用率。

一、GCD的基本使用

1、 GCD 中的 两个核心 概念 :
任务 执行什么任务 .
队列 用来存放任务 . ( 用来调度任务 )
2、 GCD 使用的 2 个步骤 :
1. 任务 .   ( 确定想做的事情 )
2 . 任务添加 到队列中 .
GCD 自动 队列 中的任务 取出 , 放到 对应的线程 中执行 .
遵循队列的 FIFO 原则 : 先进先出 .
3、 同步和异步 的区别 : (是否开启新线程)
同步 : 在当前线程中执行 .
异步 : 在另一条线程中执行 .
4、并行与串行队列 : (任务的执行方式)
并行对列 : 异步 情况下 , 让多个任务 并发执行 .
串行队列 : 一个任务 执行完后 , 再执行 下一个任务 .

队列又分为几种:自定义的队列、全局队列、主队列
基本使用代码如下:

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
    [self gcdDemo4];
}

#pragma mark - 串行队列
- (void)gcdDemo1{
    // 1. 串行队列
    // 在使用GCD的时候,先敲dispatch
    // 在C语言中,定义对象通常是以 _t 或者 Ref 结尾的
    dispatch_queue_t q = dispatch_queue_create("myQueueName", DISPATCH_QUEUE_SERIAL); //DISPATCH_QUEUE_SERIAL 的值为 NULL
    
    NSLog(@"%@", [NSThread currentThread]);
    
    // 2. 同步任务 sync(实际开发中没用)
    for (int i = 0; i < 10; i++) {
        dispatch_sync(q, ^{
            NSLog(@"%@ - %d", [NSThread currentThread], i);
        });
    }
    
    // 2. 异步任务 async,能够开线程
    // 串行队列中,异步任务最多只能开一条线程,所有任务顺序执行!
    // 串行队列,异步任务,在多线程中,是斯坦福大学最推荐的一种多线程方式!
    // 优点:将任务放在其他线程中工作,每个任务顺序执行,便于调试
    // 缺点:并发能力不强,最多只能使用一条线程!
    for (int i = 0; i < 10; i++) {
        dispatch_async(q, ^{
            NSLog(@"%@ - %d", [NSThread currentThread], i);
        });
    }
}


#pragma mark - 并行队列
- (void)gcdDemo2{
    // 1. 并行队列
    dispatch_queue_t q = dispatch_queue_create("myQueueName", DISPATCH_QUEUE_CONCURRENT);
    
    // 非ARC中,需要自己释放队列
    //    dispatch_release(q);
    
    // 2. 同步任务,不会开启新的线程
    // 在实际开发中,同步任务可以保证执行完成之后,才让后续的异步任务开始执行,用于控制任务之间的先后顺序,如在后台线程中,处理“用户登录”等
    for (int i = 0; i < 10; i++) {
        dispatch_sync(q, ^{
            NSLog(@"%@ - %d", [NSThread currentThread], i);
        });
    }
    
    // 3. 异步任务,会在多条线程上工作,具体开多少条线程,由系统决定
    // 仍然是按照任务添加到队列中的顺序被调度,只是执行先后可能会有差异!
    // *** 能够将耗时的操作,放到子线程中工作
    // *** 与串行队列异步任务相比,并发性能更好!但是执行的先后顺序,不固定
    for (int i = 0; i < 10; i++) {
        dispatch_async(q, ^{
            NSLog(@"%@ - %d", [NSThread currentThread], i);
        });
    }
}


#pragma mark - 全局并行(并发)队列(使用更为普遍一些)
- (void)gcdDemo3{
    // 1. 获取全局队列(与自定义并行队列的区别就是名字显示,其他都一样)
    dispatch_queue_t q = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    // 使用全局队列,不需要考虑共享的问题
    
    // 2. 同步任务
    for (int i = 0; i < 10; i++) {
        dispatch_sync(q, ^{
            NSLog(@"%@ - %d", [NSThread currentThread], i);
        });
    }
    
    // 3. 异步任务
    for (int i = 0; i < 10; i++) {
        dispatch_async(q, ^{
            NSLog(@"%@ - %d", [NSThread currentThread], i);
        });
    }
}


#pragma mark - 主队列(专门调度在主线程上工作的队列,不能开线程)
- (void)gcdDemo4{
    // 1. 获取主队列
    dispatch_queue_t q = dispatch_get_main_queue();
    
    // 2. 不要同步任务(死锁!!!)
    //    dispatch_sync(q, ^{
    //        NSLog(@"不会输出的!!!");
    //    });
    
    // 3. 异步任务,在主线程上依次顺序执行
    for (int i = 0; i < 10; i++) {
        dispatch_async(q, ^{
            NSLog(@"%@ - %d", [NSThread currentThread], i);
        });
    }
}

二、GCD进行线程间通讯

这里从主线程调用下载图片的方法,开启一个线程下载,然后在该线程任务完成后,返回主线程。

- (void)downloadImage{
    // 1. 全局并行队列
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    
    // 2. 异步任务
    dispatch_async(queue, ^{
        NSLog(@"开始下载图片 %@", [NSThread currentThread]);
        //。。。。
        NSLog(@"完成下载图片 %@", [NSThread currentThread]);
        
        // 3. 通知主队列更新UI
        // 给主队列,添加一个异步任务,更新UI
        dispatch_async(dispatch_get_main_queue(), ^{
            //可以做更新UI操作。。。。
        });
    });
}


下面的2篇不错,可以更好的理解:
http://blog.csdn.net/onlyou930/article/details/8225906

http://www.cnblogs.com/pure/archive/2013/03/31/2977420.html


转载请注明出处:http://blog.csdn.net/xn4545945  






  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值