本文仅做为我的学习总结记录使用!能力有限,不免会有疏漏和错误,还望指出。共同进步。html
工做学习IOS已经有半年了,一直都想抽出时间记录一下本身的学习和工做经验,但都写到一半,就没有而后了。关于并发编程,其实国外国内已经有各类牛人总结过很是棒的文章,但大多都是碎片化的文章。我就我的感觉而言,总结一下并发编程以及相关的一些知识。编程
关于并发编程,大部分的教程要么是直接介绍GCD(Grand Central Dispatch
),要么就是上一大堆的Operation Queues,还有介绍Threads来完成并发。后端
在移动和桌面操做系统中,苹果提供了相同的并发编程API。 经常使用的分别是:pthread和NSThread,Grand Central Dispatch(GCD)以及NSOperationQueue
因为高层API是基于底层API构建的,因此首先将从底层的API开始介绍,而后逐步介绍高层API,不过在具体编程中,选择API的顺序恰好相反:由于大多数状况下,选择高层的API不只能够完成底层API能完成的任务,并且可以让并发模型变得简单。api
Threads
线程(thread)是组成进程的子单元,操做系统的调度器能够对线程进行单独的调度。实际上,全部的并发编程API都是构建于线程之上的——包括GCD和操做队列(operation queues)。安全
通常在工做中,都不会使用pthread和NSThread,由于使用pthread或NSThread会引起一个问题:你建立了8个线程,而后在这些线程中调用了框架代码,这些代码也建立了一样的线程(其实它并不知道你已经建立好线程了),这样会很快产生成千上万个线程,最终致使你的程序被终止执行——线程实际上并非免费的咖啡,每一个线程的建立都会消耗一些内容,以及相关的内核资源
基于队列的并发编程API:GCD和operation queue。它们经过集中管理一个线程池(被没一个任务协同使用),来解决上面遇到的问题闭包
Grand Central Dispatch
经过GCD,开发者不用再直接跟线程打交道了,只须要向队列中添加block代码便可,GCD在后端管理着一个线程池。GCD不只决定着哪一个线程(block)将被执行,它还根据可用的系统资源对线程池中的线程进行管理——这样能够不经过开发者来集中管理线程,缓解大量线程的建立,作到了让开发者远离线程的管理。
更多GCD的使用请参考:Low-Level Concurrency APIs并发
Operation Queues
操做队列(operation queue)是基于GCD封装的一个队列模型。GCD提供了更加底层的控制,而操做队列在GCD之上实现了一些方便的功能,这些功能对于开发者来讲会更好、更安全。
关于Operation Queues比较好的文章:Common Background Practices框架
NSObject
若是你只想让一些代码在后台执行,NSObject也提供了方法。这些方法的名字中都有“performSelector:”,最简单的就是“performSelectorInBackground:withObject:”,它能在后台执行一个方法。它经过建立一个线程来运行方法。定义这些方法必须遵循一下限制:函数
这些方法运行在各自的线程里,所以你必须为这些Cocoa对象建立一个自动释放池,而主动释放池是与主线程相关的。(arc,请无视)学习
这些方法不能有返回值,而且要么没有参数,要么只能有一个参数。换句话说,你只能使用如下代码格式中的一种。
记住这些限制,咱们实现的代码应该以下所示:
-(void)myBackgroudMethod{ @autoreleasepool{ //todo } }
或
-(void)myOtherBackgroudMethod:(id)myObject{ @autoreleasepool{ // TODO } }
同时调用的时候,应该像这样。
[self performSelectorInBackground:@selector(myBackgroudMethod) withObject:nil]; [self performSelectorInBackground:@ selector(myOtherBackgroudMethod:) withObject: myObject];
这样就完成了。当方法执行结束后,OC运行时会特意清理并弃掉线程。须要注意,方法执行结束后并不会通知你:这是比较简单的代码
配合NSObject的
performSelectorOnMainThread
也能达到GCD的效果:
-(void)myOtherBackgroudMethod:(id)myObject{ @autoreleasepool{ // TODO [self performSelectorOnMainThread:@selector(updateUI:) withObject:obj waitUntilDone:YES]; } } -(void)updateUI:(NSObject *)obj{ // TODO }
我的认为比较好的文章:
初识block:
Block剧终:Objective-C中的闭包性和匿名函数:
Gcd说到底其实就是方便操做线程的一个开源库,并使用了block当作参数来传递这一特性。
Block其实就是OC的匿名函数,并具备闭包的特性,并且能够很容易的获取上下文的信息。和gcd有着本质的区别
以上都是我学习中的总结和注释而已。篇幅很少,大多都是站在别人的肩膀上。主要是给本身回顾和完善知识体系用的。若是有不对的地方,欢迎指出。