上一篇文章我对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];// 主线程中更新UIdispatch_async(dispatch_get_main_queue(), ^{self.imageView1.image = image;});});dispatch_async(queue, ^{NSLog(@"%@开始下载第二张图片",[NSThread currentThread]);UIImage *image = [self downloadImageWithURL:strURL2];// 主线程中更新UIdispatch_async(dispatch_get_main_queue(), ^{self.imageView2.image = image;});});dispatch_async(queue, ^{NSLog(@"%@开始下载第三张图片",[NSThread currentThread]);UIImage *image = [self downloadImageWithURL:strURL3];// 主线程中更新UIdispatch_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还有很多其他的用处,我会在下一篇文章中讲!

转载于:https://www.cnblogs.com/doujiangyoutiao/p/6030236.html

iOS多线程之5.GCD的基本使用相关推荐

  1. iOS多线程之GCD小记

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

  2. (五十五)iOS多线程之GCD

    GCD的全称为Grand Central Dispatch,翻译为大中央调度,是Apple开发的一个多线程编程解决方法. 进程和线程的概念: 正在进行中的程序被称为进程,负责程序运行的内存分配,每一个 ...

  3. IOS多线程之Block编程

    1 什么是block iOS SDK 4.0開始,Apple引入了block这一特性.字面上说,block就是一个代码块.可是它的奇妙之处在于在内联(inline)运行的时候(这和C++非常像)还能够 ...

  4. iOS多线程之7.NSOperation的初识

    NSOperation和GCD一样,不用我们管理线程的生命周期,加锁等问题,只要把操作封装进NSOperation中,系统会自动帮我们创建线程,执行操作.而且他是面向对象的,我们看起来更容易理解,使用 ...

  5. (五十六)iOS多线程之NSOperation

    NSOpertation是一套OC的API,是对GCD进行的Cocoa抽象. NSOperation有两种不同类型的队列,主队列和自定义队列. 主队列运行于主线程上,自定义队列在后台运行. [NSBl ...

  6. ios多线程之NSThread头文件详解

    1.NSThread 头文件中的相关方法 //获取当前线程+(NSThread *)currentThread; //创建线程后自动启动线程 + (void)detachNewThreadSelect ...

  7. linux 线程pthread_detach,linux线程之pthread_join和pthread_detach

    在任何一个时间点上,线程是可结合的(joinable)或者是分离的(detached).一个可结合的线程能够被其他线程收回其资源和杀死.在 被其他线程回收之前,它的存储器资源(例如栈)是不释放的.相反 ...

  8. 多线程之NSThread

    关于多线程会有一系列如下: 多线程之概念解析 多线程之pthread, NSThread, NSOperation, GCD 多线程之NSThread 多线程之NSOperation 多线程之GCD ...

  9. iOS多线程编程之NSThread的使用(★★★推荐,为原作者点赞★★★)

    文章来源:http://blog.csdn.net/totogo2010/article/details/8010231 1.简介: 1.1 iOS有三种多线程编程的技术,分别是: 1..NSThre ...

  10. Android多线程之ArrayBlockingQueue源码解析

    阻塞队列系列 Android多线程之LinkedBlockingQueue源码解析 Android多线程之SynchronousQueue源码解析 Andorid多线程之DelayQueue源码分析 ...

最新文章

  1. 计算机网络-TCP运输连接管理
  2. 一起学nRF51xx 5 -  ppi
  3. Kubernetes可以代替Docker,可笑
  4. java后端英文_计算机程序员 前后台 英文怎么说
  5. c语言退格键ascii码,【回车键的ASCII码是多少】
  6. 让你浏览器飞起来的电脑插件合集
  7. “舌战群儒”的技术分析
  8. EventListenerTouchOneByOne::create() 单点触摸
  9. arm怎么运行python_给arm板编译移植python(一)
  10. c语言程序设计精髓第六章编程题
  11. NVIDIA GeForce 800系列详细配置参数
  12. 邓奶奶坐轮椅泪别袁爷爷
  13. 使用pip报错:Could not fetch URL https://pypi.org/simple/selenium/: There was a problem confirming the ss
  14. 回调函数,监听函数 关系 个人学习理解
  15. python的repl模式_为什么解释器的交互模式又叫 REPL
  16. SAP产品合规管理(Product Compliance)之危险品管理(Dangerous Goods Management)功能讲解
  17. 案例—考勤后台管理系统需求
  18. nginx报错找不到指定路径
  19. 补充Live555推实时流
  20. Measure()与onMeasure()

热门文章

  1. 生活中的思维风暴——读《谁是谷歌想要的人才》精彩题目小记(二)
  2. 在OpenStack虚拟机实例中创建swap分区的一种方法
  3. 极品菜系列3 [图]
  4. MFC中让自定义的类能响应消息
  5. (一)SVM的八股简介
  6. OC可变数组的常用操作
  7. 2019年2月22日 深入理解计算机系统(CS:APP)第一章读书笔记
  8. 记一下vue.js事件的修饰等问题
  9. Aix5~6小机运维
  10. T-SQL: 读取磁盘文件