有过编程经验的人,基本都会接触到多线程这块。java
在java中以及Android开发中,大量的后台运行,异步消息队列,基本都是运用了多线程来实现。ios
一样在,在ios移动开发和Android基本是很相似的一种模型。编程
可是不少时候,在应用开发中,咱们会发现自己并无本身编码去处理一些并发的事件,去开辟新的子线程等等。api
(虽然通常的调用sdk发起一个网络请求,系统都是会默认给你新起一个线程去处理的)。数组
整个程序看上去基本就是在Main线程中执行。安全
确实也是这样的一种现象,由于咱们基本都是在操做控件的布局,对控件数据添加,对于UI对象的更新都是在主线程的进行。网络
即使等下咱们看到咱们开启了一个新的子线程用来获取处理数据,最后仍是须要经过通知UI主线程来刷新。多线程
固然了,ios自己也是和大部分语言同样,有NSThread线程类(咱们都知道java中咱们用到这个类)。并发
这些系统比较底层的api类,能够被我用来书写本身的并发线程和操做队列。异步
学过Android的咱们都知道Handler,Looper这个概念,Looper说白了就是一个主线程的消息循环队列,handler通常理解就是用于子线程和UI主线程一些数据交互。
看了下ios的GCD特性,发现他们之间很有几分类似。
1.下面来看下如何使用gcd编程的异步
dispatch_async开启一个异步操做,第一个参数是指定一个gcd队列,第二个参数是分配一个处理事物的程序块到该队列。
dispatch_get_global_queue(0, 0),指用了全局队列。
通常来讲系统自己会有3个队列。
global_queue,current_queue,以及main_queue.
获取一个全局队列是接受两个参数,第一个是我分配的事物处理程序块队列优先级。分高低和默认,0为默认2为高,-2为低
处理完事物后,须要将结果返回给或者是刷新UI主线程,一样,和上面同样,抓取主线程,程序块操做。
//天啊,手贱不当心点到了home间,会退后发现没保存~~~写的并发一块内容都没了!!!
二:GCD之并发概念
其实对于编程中,咱们一直说起到的几个概念,同步,异步,并发,锁等。
有时以为一会儿还真说不清。
下面咱们以上面提到的图片加载来看下这3个概念个人理解
1同步:
假设我要加载10个图片,我如今拥有这些图片的资源地址,保存在一个数组中。
咱们先以获取第一张图片来举例:
同步执行的概念就是,我获取完第一张图片的,
执行了for循环第一句返回了img后,我才能执行第二句,UI界面的刷新。
若是第一句返回的时间须要10秒,那我程序的响应就仿佛一直卡在这里同样,我没法进行其余操做。必须等它返回!!
所以,同步的一个很好理解的感念就是,一步走到黑。
2.异步
看了这代码,咱们会说,异步操做那个假设仍是要10秒啊,整体看来,执行一张图片的时间加载仍是要在10秒左右啊,
貌似异步没什么鸟用么。可是,别忽略了其中一点,也黑丝核心的一点,此时咱们图片获取操做放在里一个线程队列里,
此刻,虽然咱们看着图片的加载仍是须要10秒才会出来,可是,在这10秒期间,咱们的UI主线程是能够操做的,好比界面上有个按钮,你是能够按的
而不是如上面的同步,在10面期间,我是只能干等着,什么都作不了。
异步的核心概念就是一个新线程,一个消息回调通知。
3.并行
咱们仍是以上代码为例。前面我强调了,咱们只看一张图片的加载,如今,回到咱们第一眼看到代码的思惟上去,
一个for循环。其实上面代码事后,我是建立了10个异步线程。
好吧,到此,咱们应该明白这三个概念了。
同步,其实我前面的例子举得有些局限,就是这个例子自己就说明不须要同步执行,而后给你们大感受是
同步是编程中一个忌讳点同样,其实否则,不少时候。咱们真是须要同步来作一些限制(好比线程中提出的同步锁?听着就感受有用么
虽然可能并不如咱们想的那样的运用同步,可是至少说明这个概念一样是有用的)
我仍是以刚才那个加载图片为例子,来个简单的说明如何运用同步的好处。
固然,我只是模拟一个同步的状况。
假设咱们如今图片的加载是这样的,图片自己为在加载前是一个默认的图片,上面写着,点击我加载,点击后会调用网络加载方法,而后图片显示加载中,
而后咱们双击图片时(固然,理论上是在加载完后)读取图片网络图片放大,好吧,到这里应该能想到要表达的状况了。
整个流程应该是点击图片->加载->双击查看。那若是成了点击->加载中(以返回了图片的做者和信息)-》双击图片(经过前面请求返回的大图连接显示大图)-》
彻底加载返回(返回了大图连接)。此时咱们看不到图像的大图了。由于咱们操做在返回前了,也就是说,
不少时候,咱们下一个动做的操做必须须要用到前面一个操做的数据时,咱们会给他作认为的同步编程,好比加个按钮锁。
这是咱们又会疑惑道,下一个执行须要用到前一个执行的,那第一个例子中的for循环的第二句不是要用到么,这么说
他们必需要同步啊,若是你这么想了,好巧,咱们想到一块去了~
可是,注意,前面咱们到的异步是为了解决我点击其余按钮的操做,而不是说更新UI操做。下载和更新UI操做在咱们看来必须是同步的
这是对的,可是那种作致使了系统自己一些监听事件监听到点击处理在那个请求以后了,这边的加载图片其实要当作一次事件执行,
由于对于事件的这一抽象单元,实际上是一种可人为定义的宽广度。
也就是说,一次数据获取和图像填充,其实算是一个图像获取加载事件,事件能够说包含两个单元,加载和填充。
而整个这个事件对于咱们点击其余按钮并没有关系,那么也就说明了无需同步。
有道理啊,可是若果咱们要点击这个图片呢,也就是回到刚才那个能够双击的假设。
此处也许我么又忽略了一点为何加载中咱们能点击双击呢,也就这样的假设是获取图片已经作了异步,可是咱们下一步操做又是须要同步的
所以作了人为的同步锁定。
好了,说的太多了,当时至少咱们明白两点
异步多是为了反正耗时操做形成的主线程堵塞,
同步是为了解决一些没必要要错误和麻烦。也许到这里,咱们脑中会联想到的所谓的线程安全性。
其实同步以及同步锁,倒是应该是考虑到这样的没必要要和不安全因素。
最后在简单阐述下异步和并发关系。
其实看了上面说的,异步只是提供了一种多线程处理的概念,
并发是更像是异步的一种大规模实现。
就比如说,异步提出了能够用小弟去收保护费,收完了告诉并交给本身,而我在期间作其余要作的事。
并发忽然想到,异步这个颇有道理啊,那我有4个地方要收,一个小弟去收,虽然我仍是能够闲着作其余的事,
可是小弟跑四个地方,我拿到钱所须要的时间仍是和我本身去收同样的,只不过我不用那么费劲了,还能作其余事了。
所以,并发以为应该派四个小弟去,由于每一个场地的保护费各不相干的。(刚看了个纽约黑帮~)。
所以说,异步解决了线程堵塞,而并发则是在异步的基础上,提升了符合特性事件的处理时间效率。
固然,若是10个图片自己相互间是没什么联系,可是,最后一个事件须要处理计算这10个图片的总容量值。
那么能够用 dispatch_group_async。
具体就看文档吧。
整体来讲,看了iosGCD这块,一是让我熟悉了block编程特性,还有是熟悉如何使用ios提供的GCD特性
来完成多线程编程。