有过编程经验的人,基本都会接触到多线程这块。

在java中以及Android开发中,大量的后台运行,异步消息队列,基本都是运用了多线程来实现。

同样在,在ios移动开发和Android基本是很类似的一种模型。

但是很多时候,在应用开发中,我们会发现本身并没有自己编码去处理一些并发的事件,去开辟新的子线程等等。

(虽然一般的调用sdk发起一个网络请求,系统都是会默认给你新起一个线程去处理的)。

整个程序看上去基本就是在Main线程中执行。

确实也是这样的一种现象,因为我们基本都是在操作控件的布局,对控件数据添加,对于UI对象的更新都是在主线程的进行。

即便等下我们看到我们开启了一个新的子线程用来获取处理数据,最后还是需要通过通知UI主线程来刷新。

当然了,ios本身也是和大部分语言一样,有NSThread线程类(我们都知道java中我们用到这个类)。

这些系统比较底层的api类,可以被我用来书写自己的并发线程和操作队列。

学过Android的我们都知道Handler,Looper这个概念,Looper说白了就是一个主线程的消息循环队列,handler一般理解就是用于子线程和UI主线程一些数据交互。

看了下ios的GCD特性,发现他们之间颇有几分相似。

1.下面来看下如何使用gcd编程的异步

  1. dispatch_async(dispatch_get_global_queue(0, 0), ^{
  2. // 处理耗时操作的代码块...
  3. //通知主线程刷新
  4. dispatch_async(dispatch_get_main_queue(), ^{
  5. //回调或者说是通知主线程刷新,
  6. });
  7. });

dispatch_async开启一个异步操作,第一个参数是指定一个gcd队列,第二个参数是分配一个处理事物的程序块到该队列。

dispatch_get_global_queue(0, 0),指用了全局队列。

一般来说系统本身会有3个队列。

global_queue,current_queue,以及main_queue.

获取一个全局队列是接受两个参数,第一个是我分配的事物处理程序块队列优先级。分高低和默认,0为默认2为高,-2为低

  1. #define DISPATCH_QUEUE_PRIORITY_HIGH     2
  2. #define DISPATCH_QUEUE_PRIORITY_DEFAULT  0
  3. #define DISPATCH_QUEUE_PRIORITY_LOW     (-2)

处理完事物后,需要将结果返回给或者是刷新UI主线程,同样,和上面一样,抓取主线程,程序块操作。

//天啊,手贱不小心点到了home间,会退后发现没保存~~~写的并发一块内容都没了!!!

二:GCD之并发概念

其实对于编程中,我们一直提及到的几个概念,同步,异步,并发,锁等。

有时觉得一下子还真说不清。

下面我们以上面提到的图片加载来看下这3个概念我的理解

1同步:

  1. for (int i = 0 ; i < 10; i++) {
  2. UIImage *img = [self getImgeWith:[urlArr objectForIndex:i]];
  3. [myImgV[i] setImage:img];
  4. }

假设我要加载10个图片,我现在拥有这些图片的资源地址,保存在一个数组中。

我们先以获取第一张图片来举例:

同步执行的概念就是,我获取完第一张图片的,

执行了for循环第一句返回了img后,我才能执行第二句,UI界面的刷新。

如果第一句返回的时间需要10秒,那我程序的响应就仿佛一直卡在这里一样,我无法进行其他操作。必须等它返回!!

因此,同步的一个很好理解的感念就是,一步走到黑。

2.异步

  1. for (int i = 0 ; i < 10; i++) {
  2. dispatch_async(dispatch_get_global_queue(0, 0), ^{
  3. // 处理耗时操作的代码块...
  4. UIImage *img = [self getImgeWith:[urlArr objectForIndex:i]];
  5. //通知主线程刷新
  6. dispatch_async(dispatch_get_main_queue(), ^{
  7. //回调或者说是通知主线程刷新,
  8. [myImgV[i] setImage:img];
  9. });
  10. });

看了这代码,我们会说,异步操作那个假设还是要10秒啊,总体看来,执行一张图片的时间加载还是要在10秒左右啊,

貌似异步没什么鸟用么。但是,别忽略了其中一点,也黑丝核心的一点,此时我们图片获取操作放在里一个线程队列里,

此刻,虽然我们看着图片的加载还是需要10秒才会出来,但是,在这10秒期间,我们的UI主线程是可以操作的,比如界面上有个按钮,你是可以按的

而不是如上面的同步,在10面期间,我是只能干等着,什么都做不了。

异步的核心概念就是一个新线程,一个消息回调通知。

3.并行

我们还是以上代码为例。前面我强调了,我们只看一张图片的加载,现在,回到我们第一眼看到代码的思维上去,

一个for循环。其实上面代码过后,我是创建了10个异步线程。

好吧,到此,我们应该明白这三个概念了。

同步,其实我前面的例子举得有些局限,就是这个例子本身就说明不需要同步执行,然后给大家大感觉是

同步是编程中一个忌讳点一样,其实不然,很多时候。我们真是需要同步来做一些限制(比如线程中提出的同步锁?听着就感觉有用么

虽然可能并不如我们想的那样的运用同步,但是至少说明这个概念同样是有用的)

我还是以刚才那个加载图片为例子,来个简单的说明如何运用同步的好处。

当然,我只是模拟一个同步的情况。

假设我们现在图片的加载是这样的,图片本身为在加载前是一个默认的图片,上面写着,点击我加载,点击后会调用网络加载方法,然后图片显示加载中,

然后我们双击图片时(当然,理论上是在加载完后)读取图片网络图片放大,好吧,到这里应该能想到要表达的情况了。

整个流程应该是点击图片->加载->双击查看。那如果成了点击->加载中(以返回了图片的作者和信息)-》双击图片(通过前面请求返回的大图链接显示大图)-》

完全加载返回(返回了大图链接)。此时我们看不到图像的大图了。因为我们操作在返回前了,也就是说,

很多时候,我们下一个动作的操作必须需要用到前面一个操作的数据时,我们会给他做认为的同步编程,比如加个按钮锁。

这是我们又会疑惑道,下一个执行需要用到前一个执行的,那第一个例子中的for循环的第二句不是要用到么,这么说

他们必须要同步啊,如果你这么想了,好巧,我们想到一块去了~

但是,注意,前面我们到的异步是为了解决我点击其他按钮的操作,而不是说更新UI操作。下载和更新UI操作在我们看来必须是同步的

这是对的,但是那种做导致了系统本身一些监听事件监听到点击处理在那个请求之后了,这边的加载图片其实要看成一次事件执行,

因为对于事件的这一抽象单元,其实是一种可人为定义的宽广度。

也就是说,一次数据获取和图像填充,其实算是一个图像获取加载事件,事件可以说包含两个单元,加载和填充。

而整个这个事件对于我们点击其他按钮并无关系,那么也就说明了无需同步。

有道理啊,但是若果我们要点击这个图片呢,也就是回到刚才那个可以双击的假设。

此处也许我么又忽略了一点为什么加载中我们能点击双击呢,也就这样的假设是获取图片已经做了异步,但是我们下一步操作又是需要同步的

因此做了人为的同步锁定。

好了,说的太多了,当时至少我们明白两点

异步可能是为了反正耗时操作造成的主线程堵塞,

同步是为了解决一些不必要错误和麻烦。也许到这里,我们脑中会联想到的所谓的线程安全性。

其实同步以及同步锁,却是应该是考虑到这样的不必要和不安全因素。

最后在简单阐述下异步和并发关系。

其实看了上面说的,异步只是提供了一种多线程处理的概念,

并发是更像是异步的一种大规模实现。

就好比说,异步提出了可以用小弟去收保护费,收完了告诉并交给自己,而我在期间做其他要做的事。

并发突然想到,异步这个很有道理啊,那我有4个地方要收,一个小弟去收,虽然我还是可以闲着做其他的事,

但是小弟跑四个地方,我拿到钱所需要的时间还是和我自己去收一样的,只不过我不用那么费劲了,还能做其他事了。

因此,并发觉得应该派四个小弟去,因为每个场地的保护费各不相干的。(刚看了个纽约黑帮~)。

因此说,异步解决了线程堵塞,而并发则是在异步的基础上,提高了符合特性事件的处理时间效率。

当然,如果10个图片本身相互间是没什么联系,但是,最后一个事件需要处理计算这10个图片的总容量值。

那么可以用 dispatch_group_async。

具体就看文档吧。

总体来说,看了iosGCD这块,一是让我熟悉了block编程特性,还有是熟悉如何使用ios提供的GCD特性

来完成多线程编程。

IOS学习之十七:Grand Central Dispatch(GCD)编程基础的更多相关文章

  1. IOS 多线程编程之Grand Central Dispatch(GCD)介绍和使用 多线程基础和练习

    介绍:前面内容源自网络 Grand Central Dispatch 简称(GCD)是苹果公司开发的技术,以优化的应用程序支持多核心处理器和其他的对称多处理系统的系统.这建立在任务并行执行的线程池模式 ...

  2. [转] iOS多线程编程之Grand Central Dispatch(GCD)介绍和使用

    介绍: Grand Central Dispatch 简称(GCD)是苹果公司开发的技术,以优化的应用程序支持多核心处理器和其他的对称多处理系统的系统.这建立在任务并行执行的线程池模式的基础上的.它首 ...

  3. iOS 多线程编程之Grand Central Dispatch(GCD)

    介绍: Grand Central Dispatch 简称(GCD)是苹果公司开发的技术,以优化的应用程序支持多核心处理器和其它的对称多处理系统的系统.这建立在任务并行运行的线程池模式的基础上的. 它 ...

  4. iOS多线程编程之Grand Central Dispatch(GCD)介绍和使用

    http://blog.csdn.net/totogo2010/article/details/8016129 GCD很好的博文

  5. Grand Central Dispatch (GCD)

    Grand Central Dispatch (GCD) Reference Grand Central Dispatch (GCD) comprises language features, run ...

  6. iOS 中NSOperationQueue,Grand Central Dispatch , Thread的上下关系和区别

    In OS X v10.6 and later, operation queues use the libdispatch library (also known as Grand Central D ...

  7. Grand Central Dispatch(GCD)详解(转)

    概述 GCD是苹果异步执行任务技术,将应用程序中的线程管理的代码在系统级中实现.开发者只需要定义想要执行的任务并追加到适当的Dispatch Queue中,GCD就能生成必要的线程并计划执行任务.由于 ...

  8. Grand Central Dispatch(GCD)详解

    概述 GCD是苹果异步执行任务技术,将应用程序中的线程管理的代码在系统级中实现.开发者只需要定义想要执行的任务并追加到适当的Dispatch Queue中,GCD就能生成必要的线程并计划执行任务.由于 ...

  9. iOS开发-多线程之GCD(Grand Central Dispatch)

    Grand Central Dispatch(GCD)是一个强有力的方式取执行多线程任务,不管你在回调的时候是异步或者同步的,可以优化应用程序支持多核心处理器和其他的对称多处理系统的系统.开发使用的过 ...

  10. NSThread 子线程 Cocoa NSOperation GCD(Grand Central Dispatch) 多线程

    单词:thread 英 θred:n 线.思路.vt 穿过.vi 穿透过 一.    进程.线程 进程:正在进行中的程序被称为进程,负责程序运行的内存分配,每一个进程都有自己独立的虚拟内存空间 线程: ...

随机推荐

  1. JS验证手机号码

    对于表单的验证是添加信息的时候必不可少的. 下面是基于EasyUI-validatebox拓展的对手机.座机号的验证方法. PhoneAndMobile: { validator: function ...

  2. windows 编程 —— 消息与参数(滚动条、键盘、鼠标)

    目录: 滚动条 键盘 鼠标 滚动条ScrollBar 发送消息:WM_VSCROLL和WM_HSCROLL 参数wParam:wParam消息参数被分为一个低字组和一个高字组.wParam的低字组是一 ...

  3. SKLabelNode类

    继承自 SKNode:UIResponder:NSObject 符合 NSCoding(SKNode)NSCopying(SKNode)NSObject(NSObject) 框架  /System/L ...

  4. hadoop1.X安装

    1.      配置主机的名称 master,slave1,slave2 2.      安装JDK: 3.      配置IP与主机名称的映射: 192.168.0.100 master 192.1 ...

  5. iOS 在 Xcode 中重命名项目名称

    本教程使用的 Xcode 版本是Xcode 6.3.1,网上有好多的教程,都是在 Xcode 4 上做的讲解,现以本文章讲解一下如何在 Xcode 6.3.1 中重命名你的项目名称,包括你的应用名称. ...

  6. 怎样将关系型数据表转换至hbase数据表

    首先须要把关系型数据库的数据表的数据添加由 "纵向延伸",转变为HBase数据表的"横向延伸" 一.Hbase的存储结构 a)      HBase以表(HTa ...

  7. GCC编译选项

    一.看例子分析gcc 的编译选项 gcc -o hello hello.c -I /home/hello/include -L /home/hello/lib -lworld 1.-I /home/h ...

  8. VNC-Server installation on CentOS 7

    参考资料: https://www.howtoforge.com/vnc-server-installation-on-centos-7 https://linux.cn/article-5335-1 ...

  9. eclipse-android-activity_main/fragment_main文件处理

    android新建工程后,在res/layout/下有两个文件,之前用studio的时候貌似没有,只有一个文件,然后再测试Activity切换的时候,一直在纠结这个问题,下面是解决方法: 1)将fra ...

  10. js添加onclick函数

    document.getElementById('Add').setAttribute("onclick",AddNum()); 相当于不停的调用Addnum函数 应改成docum ...