- 浏览: 2962056 次
- 性别:
- 来自: 上海
文章分类
- 全部博客 (893)
- android (110)
- iphone (198)
- java (79)
- JavaScript手册-目录 (9)
- JavaScript手册-Array (19)
- JavaScript手册-Boolean (5)
- JavaScript手册-Date (50)
- JavaScript手册-Math (30)
- JavaScript手册-Number (14)
- JavaScript手册-RegExp (7)
- JavaScript手册-String (38)
- JavaScript手册-全局函数 (8)
- JavaScript实用脚本 (7)
- Others (21)
- java-jpcap (7)
- java-thread (1)
- ibm文章 (3)
- classloader (2)
- java-filter (2)
- 运行环境 (33)
- java-正则 (2)
- oracle (1)
- linux-shell (26)
- wap (1)
- sqlite (3)
- wow (1)
- jvm (1)
- git (5)
- unity3d (29)
- iap (2)
- mysql (23)
- nginx (14)
- tomcat (9)
- apache (2)
- php (1)
- ubuntu (40)
- rsa (1)
- golang (21)
- appstore (5)
- sftp (2)
- log4j (2)
- netty (18)
- 测试工具 (6)
- memcache (5)
- 设计模式 (1)
- centos (8)
- google_iab (5)
- iOS专题 (4)
- mac (10)
- 安装配置帮助手册 (2)
- im4java_graphicsmagick (5)
- inotify-tools (1)
- erlang (6)
- 微信支付 (1)
- redis (8)
- RabbitMQ (5)
最新评论
-
heng123:
Netty视频教程https://www.douban.com ...
netty4.0.23 初学的demo -
maotou1988:
使用Netty进行Android与Server端通信实现文字发 ...
netty4.0.23 初学的demo -
码革裹尸:
非常感谢,正好用上
android 呼入电话的监听(来电监听) -
rigou:
提示的/222.177.4.242 无法链接到ip地址,是什 ...
通过 itms:services://? 在线安装ipa ,跨过app-store -
duwanbo:
GridView与数据绑定
详解IOS开发应用之并发Dispatch Queues
转载自:http://mobile.51cto.com/iphone-283323.htm
详解IOS开发应用之并发Dispatch Queues是本文介绍的内容,我们几乎可以调度队列去完成所有用线程来完成的任务。调度队列相对于线程代码更简单,易于使用,更高效。下面讲主要简述调度队列,在应用中如何使用调度队列去执行任务。
1、关于调度队列 所有的调度队列都是先进先出队列,因此,队列中的任务的开始的顺序和添加到队列中的顺序相同。GCD自动的为我们提供了一些调度队列,我们也可以创建新的用于具体的目的。 下面列出几种可用的调度队列类型以及如何使用。 (1)serial queues(串行队列)又称私有调度队列(private),一般用再对特定资源的同步访问上。我们可以根据需要创建任意数量的串行队列,每一个串行队列之间是并发的。 (2)并行队列,又称global dispatch queue。并行队列虽然可以并发的执行多个任务,但是任务开始执行的顺序和其加入队列的顺序相同。我们自己不能去创建并行调度队列。只有三个可用的global concurrent queues。 (3)main dispatch queue 是一个全局可用的串行队列,其在行用程序的主线程上执行任务。此队列的任务和应用程序的主循环(run loop)要执行的事件源交替执行。因为其运行在应用程序的主线程,main queue经常用来作为应用程序的一个同步点。 2、关于队列的一些技术 除了调度队列,GCD还提供了一些有用的技术来帮助我们管理代码。
dispath group ,dispatch semaphore, dispath sources
3、使用blocks去实现tasks
block objects是基于C语言的特征,可以用在C,C++ Objective-c中。一个block虽然和函数指针有些相似,但是实际上代表一个底层数据结构,类似与对象,有编译器去创建和管理。
block的一个优势是可以使用其自己作用域外的变量,例如,一个block可以读取其父作用域的变量值,此值是copy到了block heap的数据结构中。当block被加入到dispatch queue中,这些值通常为只读形式。
block的声明和函数指针类似,只是把*改为了^,我们可以传递参数给block,也可以接收其返回的值。
4、创建和管理调度队列
(1)获得全局并发调度队列(global concurrent dispath queues)
系统给每一个应用程序提供了三个concurrent dispatch queues。这三个并发调度队列是全局的,它们只有优先级的不同。因为是全局的,我们不需要去创建。我们只需要通过使用函数dispath_get_global_queue去得到队列,如下:
dispatch_queue_t aQueue =dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
除了得到default的并发队列,还可以通过传递参数DISPATCH_QUEUE_PRIOPITY_HIGH和DISPATCH_QUEUE_PRIOPITY_LOW去得到高优先级或者低优先级的。(第二个参数是为以后扩展保留的)
虽然dispatch queue是引用计数对象,但是在此因为队列是全局的,不需要我们去retain或者release,我们需要使用的时候直接调用函数dispath_get_global_queue就可以。
(2)创建串行调度队列
当想要任务按照某一个特定的顺序执行时,串行队列是很有用的。串行队列在同一个时间只执行一个任务。我们可以使用串行队列代替锁去保护共享的数据。和锁不同,一个串行队列可以保证任务在一个可预知的顺序下执行。
和并发队列不同,我们要自己去创建和管理串行队列,可以创建任意数量的串行队列。当我们创建串行队列时,应出于某种目的,如保护资源,或者同步应用程序的某些关键行为。
下面的代码表述了怎么创建一个自定义的串行队列,函数dispath_queue_create需要两个参数,队列的名字,队列的属性。调试器和性能工具显示队列的名字帮助我们去跟踪任务是如何执行,队列的属性被保留供将来使用,应该为NULL
dispatch_queue_t queue; queue = dispatch_queue_create("com.example.MyQueue", NULL);
除了自己创建的自定义队列,系统会自动的给我创建一个串行队列并和应用程序的主线程绑定到一起。下面讲述如何获得它。
(3)运行时获得常见的队列
GCD提供了一些函数让我们能够方便的访问到common dispatch queues
使用dispatch_get_current_queue函数用来调试或者测试获得当前队列的标识。
使用函数dispatch_get_main_queue可以得到与应用程序主线程相连的串行调度队列。
(4)调度队列的内存管理
调度队列是引用计数类型,当我们创建串行调度队列时,我们要release它。可以使用函数dispatch_retain和dispatch_release去增加或者减少引用计数。
(5)在一个队列中存储自定义context information
所有的调度对象允许我们让其与一个自定义上下文数据关联,通过函数dispatch_set_context和dispatch_get_context来使用,系统不会去使用我们的自定义数据,我们自己在恰当的时间去分配和释放。
对于队列,上下文数据通常用来存储一个指向对象的指针,或者其他的数据结构,我们可以在队列的finalizer函数中去释放context data。下面将给一个例子。
(6)为队列提供一个clean up 函数。
当我们创建串行调度队列之后,我们可以让其和一个finalizer函数相连用来清理队列中需要清理的数据。我们可以使用dispatch_set_finalizer_f函数去设置一个函数,当队列的引用计数为0时会去自动的调用。使用此函数去清理和队列相关联的context data,当context 指针不会NULL时,此函数就会调用。
shows a custom finalizer function and a function that creates a queue and installs that finalizer. The queue uses the finalizer function to release the data stored in the queue’s context pointer. (The myInitializeDataContextFunction and myCleanUpDataContextFunction functions referenced from the code are custom functions that you would provide to initialize and clean up the contents of the data structure itself.) The context pointer passed to the finalizer function contains the data object associated with the queue.
void myFinalizerFunction(void *context) { MyDataContext* theData = (MyDataContext*)context; // Clean up the contents of the structure myCleanUpDataContextFunction(theData); // Now release the structure itself. free(theData); } dispatch_queue_t createMyQueue() { MyDataContext* data = (MyDataContext*) malloc(sizeof(MyDataContext)); myInitializeDataContextFunction(data); // Create the queue and set the context data. dispatch_queue_t serialQueue = dispatch_queue_create("com.example.CriticalTaskQueue", NULL); if (serialQueue) { dispatch_set_context(serialQueue, data); dispatch_set_finalizer_f(serialQueue, &myFinalizerFunction); } return serialQueue; }
5、在队列中添加一个任务
(1)有两种方式在队列中添加一个任务,同步或者异步。尽可能使用dispatch_async和dispatch_async_f 函数去执行,比同步的要首选。当我们向队列中添加一个块对象或者函数时,我们没有方法去知道此代码什么时间执行。
使用此异步不会去阻塞主线程。
虽然尽可能异步添加任务,在有些时候同步的方式去添加一个任务会防止一些同步错误。同步的方式调用函数dispatch_sync和dispatch_sync_f。此函数阻塞主线程的执行,直到指定的任务完成。
下面是代码例子:
(2)在任务完成的时候执行completion block
当任务完成时,我们应用程序需要得到通知,一遍去合并结果,在传统的异步编程中,我们可能会使用回调函数,但是在调度队列中,我们使用completion block。
void average_async(int *data, size_t len,
dispatch_queue_t queue, void (^block)(int))
{
// Retain the queue provided by the user to make
// sure it does not disappear before the completion
// block can be called.
dispatch_retain(queue);
// Do the work on the default concurrent queue and then
// call the user-provided block with the results.
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
int avg = average(data, len);
dispatch_async(queue, ^{ block(avg);});
// Release the user-provided queue when done
dispatch_release(queue);
});
}
(3)并发的执行循环迭代(loop iterations)
对于for循环,如果每一次的迭代相互都没有影响,可以并发的去执行迭代,使用函数dispatch_apply或者dispatch_apply_f 函数.
和正常的循环一样,函数dispatch_apply或者dispatch_apply_f直到所有的循环迭代完成时才返回。
如下代码:
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); dispatch_apply(count, queue, ^(size_t i) { printf("%un",i); });
(4)在主线程上执行任务
我们可以通过调用函数dispatch_get_main_queue 去去得到主线程的调度队列。
小结:详解IOS开发应用之并发Dispatch Queues的内容介绍完了,希望通过本文的学习能对你有所帮助!
发表评论
-
iOS程序运行生命周期
2015-11-10 09:05 962iOS程序运行生命周期 在文件AppDele ... -
iOS开发系列--IOS程序开发概览
2015-11-10 07:32 1175iOS开发系列--IOS程序开发概览 概览 ... -
2015年11月Xcode7.1(7B91b)打包发布苹果iOS应用指南
2015-11-09 18:29 108772015年11月Xcode7.1(7B91b) ... -
self.navigationController pushViewController执行不成功
2015-11-06 08:28 1605self.navigationControlle ... -
ios NSString format 保留小数点 float double
2015-11-05 17:37 2928ios NSString format 保留小数点 f ... -
自定义 URL Scheme 完全指南
2015-11-04 16:21 898自定义 URL Scheme 完全指南 转载 htt ... -
UIViewController生命周期方法viewDidLoad、viewWillAppear和viewDidAppear
2015-11-01 12:29 2946UIViewController生命周期 ... -
关于self.view.window与viewDidLoad、viewWillAppear、viewDidAppear
2015-11-01 09:36 2534关于self.view.window与viewD ... -
UIScreen学习记录
2015-10-31 08:18 1053UIScreen学习记录 转载自 ... -
使用NSTimer和CGAffineTransformMakeRotation实现旋转动画
2015-10-29 11:53 1824使用NSTimer和CGAffineTransform ... -
【原】iOSCoreAnimation动画系列教程(一):CABasicAnimation【包会】
2015-10-29 08:59 1020【原】iOSCoreAnimation动 ... -
iOS 在UILabel显示不同的字体和颜色
2015-10-27 08:07 1551在项目开发中,我们经常会遇到在这样一种情形:在一个UI ... -
UISlider滑动条的属性介绍以及于标签联合使用实时显示变动值
2015-10-27 08:06 1248UISlider滑动条的属性 ... -
关于使用DSLTableView下拉刷新数据遇到的问题
2015-10-23 21:17 938关于使用DSLTableView下 ... -
使用AdSupport.framework生成IDFA唯一标识符
2015-10-23 17:29 4704使用AdSupport.framework生成IDFA ... -
AppDelegate的详解
2015-10-22 17:51 674AppDelegate的详解 ... -
iOS开发问题集锦
2015-10-22 13:06 5191. Xcode开发连真机运行报错Please ver ... -
iOS 对象属性参数名定义的注意事项不能以alloc,new,copy,mutableCopy 作为开头命名
2015-10-21 15:41 1322property's synthesized g ... -
iOS-自定义的画圆或弧的UIView
2015-10-21 14:20 2650iOS-自定义的画圆或弧的UIView Cu ... -
iOS自定义的模态提示对话框
2015-10-20 14:27 6469iOS自定义的模态提示对话框 基本思路: 1.创建 ...
相关推荐
本文为读《ConcurrencyProgrammingGuide》笔记第二篇,在上篇分享了OSX和iOS应用开发中实现任务异步执行的技术以及应注意的事项之后,作者付宇轩)对Operation对象的设置与执行,以及DispatchQueues的创建与管理进行...
dispatch_queue_t queue = dispatch_queue_create("com.gcd-dispatch_group_async(gro
ios demo,dispatch_async,DISPATCH_QUEUE_CONCURRENT,多任务并发执行,自动创建多线
ios demo,dispatch_once,单例模式的应用,ios demo,dispatch_once,单例模式的应用
Grand Central Dispatch简称(GCD)是苹果公司开发的技术,以优化的应用程序支持多核心处理器和其他的对称多处理系统的系统,iOS应用程序中通过dispatch队列控制线程执行则是以并发来达到多核优化的重要途径.
This concise book shows you how to use Apple's Grand Central Dispatch (GCD) to simplify programming on multicore iOS devices and Mac OS X. Managing your application’s resources on more than one ...
精通iOS开发(第8版)是iOS应用开发基础教程,内容翔实,语言生动。作者结合大量实例,使用Swift语言循序渐进地讲解了适用于iPhone iPad开发的基本流程。新版介绍强大的iOS 10操作系统,涵盖Xcode 8的新功能,书中所有...
以上两种方式都是模拟任务block内为异步操作的情况,方式一先执行的dispatch_group_notify里的代码,后执行的dispatch_group_async里的任务代码,这与我们的初衷相违背。如果任务block内为同步操作时,则无论哪种...
dispatch_apply,dispatch_group,dispatch_barrier,dispatch_source的示例.
然后,您将学习在开发并发应用程序时可能遇到的常见并发问题,例如Race Conditions,Deadlocks等。 最后,了解线程和线程清理程序以及各种与线程相关的概念以及这些概念如何与您在本书中积累的知识相关联。 您还将...
1、通过dispatch_barrier_(a)sync添加的block会等待前边所有的block执行完(不包括回调)才执行。 2、在其后添加的block会在dispatch_barrier_(a)sync添加的block执行完之后(不包括回调)再执行; 不同点: 1、...
苹果官方文档的翻译,详细讲解。NSOperation+NSOperationQueue,GCD+dispatch_queue,RunLoop等详细介绍。
通过这篇文章,你将学会dispatch_async、dispatch_after、dispatch_once、dispatch_apply、dispatch semaphore、dispatch group等。 详细介绍查看下面文章: github....
1、信号量:就是一种可用来控制访问资源的数量的标识,设定了一个信 2、信号量主要有3个函数,分别是: 3、那么就开头提的问题,我们用代码来解决
iOS 5 Programming Cookbook是一本非常经典的iOS开发书籍,这本IOS5的实用书籍持续更新以满足新老开发者的需求,可以帮你解决在创建iPhone、iPad或者iPod应用时遇到的各种难题。这个版本包含大概100个方案,每个方案...
这本书旨在教你学会开发iOS应用,无论是简单的音乐播放器还是混合了动画、图片、多媒体、数据库和云存储的复杂应用。在这本书中你将掌握云服务、自动引用计数、storyboard,Interface Builder, 创建ad-hoc 并且在...
iOS 5 Programming Cookbook是一本非常经典的iOS开发书籍,这本IOS5的实用书籍持续更新以满足新老开发者的需求,可以帮你解决在创建iPhone、iPad或者iPod应用时遇到的各种难题。这个版本包含大概100个方案,每个方案...
详解IOS串行队列与并行队列进行同步或者异步的实例 IOS中GCD的队列分为串行队列和并行队列,任务分为同步任务和异步任务,他们的排列组合有四种情况,下面分析这四种情况的工作方式。 同步任务,使用GCD dispatch_...
这本书旨在教你学会开发iOS应用,无论是简单的音乐播放器还是混合了动画、图片、多媒体、数据库和云存储的复杂应用。在这本书中你将掌握云服务、自动引用计数、storyboard,Interface Builder, 创建ad-hoc 并且在...