上一篇文章我对GCD的几个基本概念做了介绍,但是大家看完了可能觉得对理解GCD并没有什么卵用。其实会用GCD其实很简单,只要记住两条就可以了。

1. 主队列里的任务必须在异步函数中执行。

主队列里的任务如果在同步函数中执行,就会造成死锁。什么是死锁?容我举例来说明。

代码

- (void)viewDidLoad {
[super viewDidLoad]; // 1.
dispatch_queue_t queue = dispatch_get_main_queue();
NSLog(@"开始执行%@",[NSThread currentThread]);
// 2.
dispatch_sync(queue, ^{
NSLog(@"执行任务%@",[NSThread currentThread]);
});
// 3.
NSLog(@"结束执行%@",[NSThread currentThread]);
}

日志

2016-11-04 14:27:44.261 TTTTTTTTTT[12014:139481] 开始执行<NSThread: 0x60000007d140>{number = 1, name = main}

  看到没有,主队列里的任务没有执行,程序也没有往下执行,这就叫做死锁。那又为什么会发生死锁。主队列里的任务默认都在主线程中执行,程序都把主队列里的任务放在主线程的最后面。当程序执行到2时,会把任务1放在主线程的后面,等主线程里的任务都执行完了在执行。可是这是什么函数啊?这是同步函数啊,它会堵塞当前的线程,后面的任务会等任务1执行完再执行。所以他们又开始互相等待,永远不会往下执行了。

任务1对其他任务说:你们快执行啊?你们执行完我才能执行!

其他任务对任务1说:不行啊,你执行完我们才能执行。这是同步那个二货规定的。

任务1和其他任务就开始了漫长的等待……

2. 全局并发队列里的任务在异步函数中执行才能实现并发。

代码

// 点击屏幕开始下载图片
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
NSString *strURL1 = @"http://h.hiphotos.baidu.com/zhidao/pic/item/6d81800a19d8bc3ed69473cb848ba61ea8d34516.jpg";
NSString *strURL2 = @"http://h.hiphotos.baidu.com/zhidao/pic/item/0eb30f2442a7d9334f268ca9a84bd11372f00159.jpg";
NSString *strURL3 = @"http://www.2liangli.com/uploads/allimg/141108/1-14110R12140136.png";
//获取全局并发队列
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_async(queue, ^{
NSLog(@"%@开始下载第一张图片",[NSThread currentThread]);
UIImage *image = [self downloadImageWithURL:strURL1];
// 主线程中更新UI
dispatch_async(dispatch_get_main_queue(), ^{
self.imageView1.image = image;
});
});
dispatch_async(queue, ^{
NSLog(@"%@开始下载第二张图片",[NSThread currentThread]);
UIImage *image = [self downloadImageWithURL:strURL2];
// 主线程中更新UI
dispatch_async(dispatch_get_main_queue(), ^{
self.imageView2.image = image;
});
});
dispatch_async(queue, ^{
NSLog(@"%@开始下载第三张图片",[NSThread currentThread]);
UIImage *image = [self downloadImageWithURL:strURL3];
// 主线程中更新UI
dispatch_async(dispatch_get_main_queue(), ^{
self.imageView3.image = image;
});
}); }
- (UIImage *)downloadImageWithURL : (NSString *)strURL {
NSURL *url = [NSURL URLWithString:strURL];
return [UIImage imageWithData:[NSData dataWithContentsOfURL:url]];
}

日志

2016-11-04 14:32:23.532 TTTTTTTTTT[12195:142364] <NSThread: 0x608000261500>{number = 5, name = (null)}开始下载第三张图片
2016-11-04 14:32:23.532 TTTTTTTTTT[12195:142365] <NSThread: 0x60000007fac0>{number = 3, name = (null)}开始下载第一张图片
2016-11-04 14:32:23.532 TTTTTTTTTT[12195:142368] <NSThread: 0x608000261700>{number = 4, name = (null)}开始下载第二张图片

  我们发现程序创建了三条线程,每条线程都执行下载图片的任务,三张图片几乎是同时开始下载的。这就实现了并发,也没有堵塞主线程。最重要的一点,下载完的图片,一定要在主线程更新。

如果有兴趣可以试试把并发队列里的任务放在同步函数中执行,我们就会发现三张图片的下载都是在主线程中进行的,图片好长时间才下载完。因为图片是一个一个下载的,而不像上面是同时开始下载。

至于自定义队列,我就不讲了,因为和上面的原理差不多,而且用的地方也不多。并发队列系统已经提供了,我们就不要自己创建了。至于串行队列,我们运用多线程就是为了多任务同时进行,串行队列里的任务无论在同步函数还是异步函数中,都不可能同时进行。

关于GCD还有很多其他的用处,我会在下一篇文章中讲!

iOS多线程之5.GCD的基本使用的更多相关文章

  1. iOS多线程之6.GCD的其他用法

    队列组   让队列里的任务同时执行,当任务都执行完毕时,再以通知的形式告诉程序员.举例,同时下载两张图片,两张图片都下载完了,在合成成一张. 代码: #import "ViewControl ...

  2. iOS多线程之4.GCD简介

    GCD(Grand Central Dispatch)应该是我们开发中最常用到的多线程解决方案,是苹果公司专门为多核的并行运算提出的解决方案,是基于C语言的,提供了很多非常强大的函数. GCD的优势 ...

  3. iOS多线程之8.NSOPeration的其他用法

      本文主要对NSOPeration的一些重点属性和方法做出介绍,以便大家可以更好的使用NSOPeration. 1.添加依赖 - (void)addDependency:(NSOperation * ...

  4. iOS多线程之GCD小记

    iOS多线程之GCD小记 iOS多线程方案简介 从各种资料中了解到,iOS中目前有4套多线程的方案,分别是下列4中: 1.Pthreads 这是一套可以在很多操作系统上通用的多线程API,是基于C语言 ...

  5. iOS多线程之Thread

    多线程 • Thread 是苹果官方提供的,简单已用,可以直接操作线程对象.不过需要程序员自己管理线程的生命周期,主要是创建那部分 优缺点 面向对象,简单易用 直接操作线程对象 需要自己管理线程生命周 ...

  6. iOS 多线程之GCD的使用

    在iOS开发中,遇到耗时操作,我们经常用到多线程技术.Grand Central Dispatch (GCD)是Apple开发的一个多核编程的解决方法,只需定义想要执行的任务,然后添加到适当的调度队列 ...

  7. iOS多线程之GCD详解

    GCD(Grand Central Dispatch)是基于C语言开发的一套多线程开发机制.也是目前苹果官方推荐的多线程开发方法.iOS三种多线程开发中GCD是抽象层次最高的.当然用起来也是最简单的. ...

  8. 【原】iOS多线程之NSThread、NSOperationQueue、NSObject和GCD的区别

    区别: Thread: 是这几种方式里面相对轻量级的,但也是使用起来最负责的,你需要自己管理thread的生命周期,线程之间的同步.线程共享同一应用程序的部分内存空间, 它们拥有对数据相同的访问权限. ...

  9. iOS多线程之GCD学习笔记

    什么是GCD 1.全称是Grand Central Dispatch,可译为“牛逼的中枢调度器” 2.纯C语言,提供了非常多强大的函数 GCD的优势 GCD是苹果公司为多核的并行运算提出的解决方案 G ...

随机推荐

  1. scikit-learn决策树算法类库使用小结

    之前对决策树的算法原理做了总结,包括决策树算法原理(上)和决策树算法原理(下).今天就从实践的角度来介绍决策树算法,主要是讲解使用scikit-learn来跑决策树算法,结果的可视化以及一些参数调参的 ...

  2. Objective-C中的类目,延展,协议

    Objective-C中的类目(Category),延展(Extension),协议(Protocol)这些名词看起来挺牛的,瞬间感觉OC好高大上.在其他OOP语言中就没见过这些名词,刚看到这三个名词 ...

  3. iOS - 类扩展与分类的区别

    类扩展 (Class Extension也有人称为匿名分类) 作用: 能为某个类附加额外的属性,成员变量,方法声明 一般的类扩展写到.m文件中 一般的私有属性写到类扩展 使用格式: @interfac ...

  4. spring整合hibernate的时候报异常org.hibernate.HibernateException: createQuery is not valid without active transaction

    在整合Spring4+hibernate4时候,当代码执行到dao中CRUD操作时,报了一个异常, org.hibernate.HibernateException: createQuery is n ...

  5. WebApi Controller 分类

    前言 写这篇WebApi Controller分类一是把Contrller分类的解决方法说一说,再顺便把遇到的问题和解决方法聊一聊. 说实话第一次在项目中使用WebApi感觉非常的不顺手. 遇到的问题 ...

  6. 关于一道PHP面试题的解法

    参照一个int型数组,如int[] a1=new int[]{10,9,10,20,15,3,9,8,7,1,1},编写一个方法,要求输出不重复,且降序的拼接字符串(连接字符用逗号),如上数组,输出的 ...

  7. [Java 基础]基础语法

    Java代码基本规范 大小写敏感:Java是大小写敏感的,这就意味着标识符Hello与hello是不同的. 类名:对于所有的类来说,类名的首字母应该大写.如果类名由若干单词组成,那么每个单词的首字母应 ...

  8. 20款jQuery 的音频和视频插件

    分享 20 款jQuery的音频和视频插件 Blueimp Gallery: DEMO || DOWNLOAD Blueimp gallery 主要为移动设备而设计,同时也支持桌面浏览器.可定制视频和 ...

  9. 【转】单例模式(Singleton)

    首先来明确一个问题,那就是在某些情况下,有些对象,我们只需要一个就可以了, 比如,一台计算机上可以连好几个打印机,但是这个计算机上的打印程序只能有一个, 这里就可以通过单例模式来避免两个打印作业同时输 ...

  10. 一句jQuery代码返回顶部

    一句jQuery代码返回顶部 效果体验: http://hovertree.com/texiao/yestop/ 使用方法: 只需引用jQuery库和YesTop插件,然后一句代码就可以实现返回顶部: ...