IOS学习总结(1)——关于并发

本文仅做为我的学习总结记录使用!能力有限,不免会有疏漏和错误,还望指出。共同进步。html

独白

工做学习IOS已经有半年了,一直都想抽出时间记录一下本身的学习和工做经验,但都写到一半,就没有而后了。关于并发编程,其实国外国内已经有各类牛人总结过很是棒的文章,但大多都是碎片化的文章。我就我的感觉而言,总结一下并发编程以及相关的一些知识。编程

遇到的问题

关于并发编程,大部分的教程要么是直接介绍GCD(Grand Central Dispatch
),要么就是上一大堆的Operation Queues,还有介绍Threads来完成并发。后端

  • 其实他们都能实现并发,但他们之间有什么区别呢?又有什么联系呢?
  • block和GCD的区别?
  • 关于delegate和block的使用

OS X和iOS中的并发编程

在移动和桌面操做系统中,苹果提供了相同的并发编程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,请无视)学习

  • 这些方法不能有返回值,而且要么没有参数,要么只能有一个参数。换句话说,你只能使用如下代码格式中的一种。

  1. -(void)myMethod;
  2. -(void)myMethod:(id)myObject;

记住这些限制,咱们实现的代码应该以下所示:

-(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:
Block剧终:Objective-C中的闭包性和匿名函数:

关于GCD和block之间的区别

Gcd说到底其实就是方便操做线程的一个开源库,并使用了block当作参数来传递这一特性。
Block其实就是OC的匿名函数,并具备闭包的特性,并且能够很容易的获取上下文的信息。和gcd有着本质的区别

总结

以上都是我学习中的总结和注释而已。篇幅很少,大多都是站在别人的肩膀上。主要是给本身回顾和完善知识体系用的。若是有不对的地方,欢迎指出。

参考文章:Concurrent Programming: APIs and Challenges