block 语法(ios 5上所得) DCD与Block

Main Queue
这个队列在主线程上执行它的所有任务,Cocoa 和  Cocoa   Touch 允许程序员在主线程上调用一切 UIrelated 方法。使用 dispatch_get_main_queue 函数检索到主队列的句柄。
Concurrent Queues
为了执行异步和同步任务,你可以在 GCD 中检索到这写队列。多个并发队列能够轻而易举的并行执行多
个任务,没有更多的线程管理,酷!使用 dispatch_get_global_queue 函数检索一个并发队列的句柄。
Serial Queues
无论你提交同步或者异步任务,这些队列总是按照先入先出(FIFO)的原则来执行任务,这就意味着它
们一次执行一个 Block  Object。然而,他们不在主线程上运行,所以对于那些要按照严格顺序执行并不阻塞主
线程的任务而言是一个完美的选择。使用 dispatch_queue_create 函数创建一个串行队列。一旦你使用完整队
列,必须使用 dispatch_release 函数释放它。
在 APP 生命周期内的任何时刻,你可以同时使用多个分派队列。你的系统只有一个主队列,但是你可以
创建多个串行队列来实现任何你需要 APP 实现的功能,当然是在合理的范围内。你也可以检索多个并发队列
并将任务分派给它们,任务可以通过 2 种方式传递分派队列:Block Objects  和 C 函数,这些我们会在 5.4 中详
细讲解。
Block  Object 是通常在 Objective-C 中以方法形式出现的代码包。Block  Objects 和 GCD 共同创建了一个和
谐环境,在这个环境里你能在 iOS 和 Mac OS X 上发布高性能的多线程 APPs。Block Objects 和 GCD 有什么特
别的地方呢?你可能会问。很简单:没有太多的线程!所有你要做的事情就是把代码放进 Block  Objects 然后
要求 GCD 来为你小心执行代码。Objective-C  中的 Block  Object 是编程领域所调用的一类的对象。这意味着你
可以动态生成的代码、把 Block  Object 作为参数传递给方法,并从一种方法返回一个 Block  Object。所有这些
事情能让你更容易地选择你想在运行库做什么,并且更容易改变一个程序的活动。特别的,Block  Objects 能够
通过 GCD 在单个线程上运行。作为 Objective-C 对象,Block Objects 可以看成和其他任何对象一样。


Block Operations

它们促使执行一个或多个 Block Objects.
Invocation Operations
这些允许你在另一个当前存在的对象中调用一个方法。
Plain Operations
这些都是需要被继承普通操作的类。将要执行的代码会被写入操作对象的主要方法中。
和前面提到的一样,Operations 由拥有 NSOperationQueue 数据类型的操作队列管理。再将后面提到的操作
类型(块、调用或普通操作)实例化之后,你可以把它们增加到一个操作队列中,并用这个队列来管理操作。
一个操作对象可以和其他操作对象有依存项,在执行与其相关任务之前必须等待一个或者多个操作完成。
除非你增加了依存项,否则你无法控制操作运行的顺序。例如,按照一定顺序把它们增加到一个队列上不能保
证它们按照这个顺序执行,尽管使用了队列选项。
在用操作队列和操作的过程中,有几个要点要记住:
  默认情况下,操作使用启动实例方法在启动它们的线程上运行。如果你想让操作异步工作,必须使用
一个操作队列和一个类  NSOperation,在运行的主要实例方法上分离一个新的线程。
  一个操作在开始它自己的运行之前可以等待另一个操作执行结束。但是要小心不要创建一个相互依存
操作,一个常见的错误就是争用条件。换句话说,如果 B 已经依赖了 A,不要让操作 A 依赖操作 B。
这将会导致双方永远等待下去,会占用内存甚至可能挂你的应用程序。
  操作可以取消。因此,如果你由 NSOperation 子类来创建自定义操作对象,你必须确保使用 isCancelled
方法去检查这个操作在执行与其相关的任务之前是否已被取消掉。例如,如果操作的任务是每 20 秒
检查一次网络连接的可用性,必须在每个运行开始就调用 isCancelled 实例方法来保证在尝试再次检
查网络连接之前它已经被取消掉。如果操作多花了几秒钟(比如当你下载文件的时候),在运行任
务的时候你应该定期检查 isCancelled。
  操作对象的 key-value  observing  (KVO)符合各种关键路径(如 isFinished 的 IsReady,isExecuting)。我
们将在后面的章节中讨论 Key Value Coding 和 Key Value Observing。
  如果您计划将 NSOperation 子类化并提供自定义实现,必须在操作的主要方法中创建您自己的
autorelease 池,这个 autourelease 池从 start 方法获取调用。我们将在本章后面的内容中详细讨论这个
问题。
  始终保持对创建的操作对象的引用。操作队列的并发性,使得它不可能在操作被添加到操作队列后还
会检索引用。
线程和定时器是继承 NSObject 的对象。线程比计时器要低一个级别。当 APP 在 iOS 上运行时,操作系统
为 APP 创建了至少一个线程,称作主线程,每个线程必须添加到一个运行循环中。运行循环,顾名思义,是
一个循环过程中的不同事件可以发生,如触发计时器或运行线程。关于运行循环的讨论超出了本章的范围,但
是我们在此处仍或多少提及。
将运行循环想象成一种有一个开始点、一个完成条件和一系列在其生命周期内发生的事件的循环。一个线
程或者计时器与一个运行附加到运行循环,事实上需要运行循环激活其功能。
一个 APP 的主线程是处理 UI 事件的线程。如果你在主线程执行一个长时间运行的任务,就要注意 APP
的 UI 会没有响应或者响应缓慢。为了避免这一点,你可以创建一个独立线程和/或计时器,它们会分别执行各

自的任务(即使是一个长时间运行的任务)同时又不会阻塞主线程。



简单总结关于 Block Objects 变量你必须了解的特点:
  局部变量在 Block Objects 和 Objective-C 方法中的工作原理非常相似。
  对于内联 Block  Objects,局部变脸不仅包含 Block 内部定义的变量,并且包含在 Block  Objects 执行方法
中定义的变量。(随后会有举例)
  你不能参考 self;在 Objective-C 类中运行的独立 Block  Objects,如果你需要访问 self,  就必须把 Object 
作为参数传递到 BlockObject,我们很快会看到举例。
  只有当 self 出现在创建 Block Object 的词法范围内,你可以在内联 Block Object 内参考 self。
  对于内联 Block  Objects,那些在 BlockObject 执行过程中定义的局部变量是可读写的,换句话说,对于
Block Objects 自身的局部变量来说,Block Objects 有个读写存取。
  对于内联 Block  Objects,实现 Object 的 Objective-C  方法的局部变量只能从中读取,不能写入。不过
还有一个例外,如果定义它们通过  __block  存储类型定义的话,Block  Object 可以写入此类的变
量。对此我们也会有举例。
  •假设你有一个类 NSObject 的 Object,并且在这个 Object 的执行中你使用了一个 Block  Object 与 GCD
相连,那么在这个 Block  Object 内部,你会有一个存储来读取那个支持你的 Block 执行的 NSObject
内部的声明属性。
只有当你使用声明属性的 setter  and  getter 方法你才能获取独立 Block  Objects 内部的 NSObject 的这些属
性;在一个独立 Block Object 使用 Dot Notation 方法你无法获取一个 Object 的声明属性。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值