iOS GCD(一)

通过 GCD,开发者不用再直接跟线程打交道了,只需要向队列中添加代码块即可,GCD 在后端管理着一个线程池。GCD 不仅决定着你的代码块将在哪个线程被执行,它还根据可用的系统资源对这些线程进行管理。这样可以将开发者从线程管理的工作中解放出来,通过集中的管理线程,来缓解大量线程被创建的问题


先弄清几个概念

同步:在当前线程中执行,没有开线程的能力(dispatch_sync)

异步:在新的线程中执行,有开线程的能力(dispatch_async)


串行队列:任务一个接一个的执行

并发队列:让多个任务并发(同时)执行,只有在开启线程即异步函数(dispatch_async)下有效(例如下面全局队列同步执行无效)


队列:有三种队列

主队列:是一种串行队列,能够保证任务一个接一个的执行,比较特殊的是它是唯一一个可以刷新UI的队列,所有刷新UI的操作都必须在主队列中执行,实际应用中是在子线程中执行接收数据的耗时操作,接收完成后再在主线程中刷新UI界面  用 dispatch_get_main_quene() 得到

全局队列:是一种并发队列,有四种优先级background default ,low high 用 dispatch_get_global_quene() 得到

自定义队列:可以是串行队列也可以是并发队列(取决于参数)  用disaptch_quene_create()得到


使用:

1、主线程

1️⃣主队列中使用异步执行

dispatch_queue_t mainQuene = dispatch_get_main_queue();
    NSLog(@"开始执行");
    dispatch_async(mainQuene, ^{
        NSLog(@"%@",[NSThread currentThread]);
        NSLog(@"在主队列中使用异步执行");
    });
    NSLog(@"结束执行");


执行结果

2016-12-27 10:55:21.482 GCD[932:79002] 开始执行
2016-12-27 10:55:21.483 GCD[932:79002] 结束执行
2016-12-27 10:55:21.491 GCD[932:79002] <NSThread: 0x6000000771c0>{number = 1, name = main}
2016-12-27 10:55:21.491 GCD[932:79002] 在主队列中使用异步执行



2️⃣主队列中使用同步执行

dispatch_queue_t mainQuene = dispatch_get_main_queue();
    NSLog(@"开始执行");
    dispatch_sync(mainQuene, ^{
        NSLog(@"在主队列中使用同步执行");
    });
    NSLog(@"结束执行");
    
这里会报错:原因是产生了死锁 。  这些代码是在viewDidload中执行中,主队列是串行队列,只能一个接一个任务的执行,本身就在执行,这里添加了一个任务到主队列,并且是同步执行,造成了互相等待的死锁


2、全局队列
1️⃣全局队列中同步执行

//同步执行不开启新线程,队列中的所有任务都是在本身所在队列中(现在是主队列)执行,并且是顺序执行

dispatch_queue_t globalQuene = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0);
    
    dispatch_sync(globalQuene, ^{
        NSLog(@"%@",[NSThread currentThread]);
        NSLog(@"1===");
    });
    dispatch_sync(globalQuene, ^{
        NSLog(@"%@",[NSThread currentThread]);
        NSLog(@"2===");
    });
    dispatch_sync(globalQuene, ^{
        NSLog(@"%@",[NSThread currentThread]);
        NSLog(@"3===");
    });
    dispatch_sync(globalQuene, ^{
        NSLog(@"%@",[NSThread currentThread]);
        NSLog(@"4===");
    });

执行结果

2016-12-27 11:17:10.733 GCD[995:90895] <NSThread: 0x60800007c600>{number = 1, name = main}
2016-12-27 11:17:10.733 GCD[995:90895] 1===
2016-12-27 11:17:10.734 GCD[995:90895] <NSThread: 0x60800007c600>{number = 1, name = main}
2016-12-27 11:17:10.734 GCD[995:90895] 2===
2016-12-27 11:17:10.734 GCD[995:90895] <NSThread: 0x60800007c600>{number = 1, name = main}
2016-12-27 11:17:10.734 GCD[995:90895] 3===
2016-12-27 11:17:10.734 GCD[995:90895] <NSThread: 0x60800007c600>{number = 1, name = main}
2016-12-27 11:17:10.734 GCD[995:90895] 4===


2️⃣全局队列异步执行

//异步执行不开启新线程,队列中的任务在开启的新线程中执行,开启的线程的数量不定,并且执行的顺序也不定

dispatch_queue_t globalQuene = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0);
    dispatch_async(globalQuene, ^{
        NSLog(@"%@",[NSThread currentThread]);
        NSLog(@"1===");
    });
    dispatch_async(globalQuene, ^{
        NSLog(@"%@",[NSThread currentThread]);
        NSLog(@"2===");
    });
    dispatch_async(globalQuene, ^{
        NSLog(@"%@",[NSThread currentThread]);
        NSLog(@"3===");
    });
    dispatch_async(globalQuene, ^{
        NSLog(@"%@",[NSThread currentThread]);
        NSLog(@"4===");
    });

执行结果
2016-12-27 11:18:55.217 GCD[1012:93021] <NSThread: 0x608000267280>{number = 5, name = (null)}
2016-12-27 11:18:55.217 GCD[1012:93007] <NSThread: 0x608000267340>{number = 3, name = (null)}
2016-12-27 11:18:55.217 GCD[1012:93005] <NSThread: 0x6080002674c0>{number = 6, name = (null)}
2016-12-27 11:18:55.217 GCD[1012:93004] <NSThread: 0x6000002621c0>{number = 4, name = (null)}
2016-12-27 11:18:55.217 GCD[1012:93021] 3===
2016-12-27 11:18:55.217 GCD[1012:93007] 1===
2016-12-27 11:18:55.217 GCD[1012:93005] 4===
2016-12-27 11:18:55.217 GCD[1012:93004] 2===


3、自定义队列

    //参数1 队列的名称,命名规则为应用名称id的倒序   参数2 如果是null 则创建的队列为串行队列 如果是DISPATCH_QUEUE_CONCURRENT 则创建的队列是并发队列
    dispatch_queue_t currentQuene = dispatch_queue_create("current", DISPATCH_QUEUE_CONCURRENT);
    NSLog(@"开始");
    dispatch_async(currentQuene, ^{
        NSLog(@"当前线程1:%@",[NSThread currentThread]);
    });
    dispatch_async(currentQuene, ^{
        NSLog(@"当前线程2:%@",[NSThread currentThread]);
    });
    dispatch_async(currentQuene, ^{
        NSLog(@"当前线程3:%@",[NSThread currentThread]);
    });
    NSLog(@"结束");
执行结果
2016-12-27 11:37:41.282 GCD[1109:108111] 开始
2016-12-27 11:37:41.282 GCD[1109:108111] 结束
2016-12-27 11:37:41.282 GCD[1109:108148] 当前线程2:<NSThread: 0x600000076900>{number = 4, name = (null)}
2016-12-27 11:37:41.282 GCD[1109:108145] 当前线程1:<NSThread: 0x608000070cc0>{number = 3, name = (null)}
2016-12-27 11:37:41.282 GCD[1109:108162] 当前线程3:<NSThread: 0x608000071840>{number = 5, name = (null)}


总结:

       主队列            全局队列       自定义队列(串行)自定义队列(并发)
async(异步)
未开新线程

顺序执行
开新线程

异步执行
开新线程

同步执行
开新线程

异步执行
sync(同步)
死锁
未开新线程

顺序执行
未开新线程

顺序执行
未开新线程

顺序执行


注:

1、在主队列中不能使用同步执行函数(会产生死锁)

2、只有异步执行函数才具有开新线程的能力

3、并发队列只在异步函数中有效(如果想要一个任务异步执行,必须在并发队列中使用异步函数执行)


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值