2014年6月 的存档

PList文件的XML与二进制

  Plist文件通常用于储存用户设置,也可以用于存储捆绑的信息,该功能在旧式的Mac OS中是由资源分支提供的。
  在Mac OS X 10.5之前的系统里面,使用defaults命令操作完Plist文件后,Defaults命令并不改变原来的Plist文件的编码方式,OS X支持两种编码:文本的XML方式和二进制方式. 对于二进制方式,用户无法使用文本编辑或者如cat命令等来显示该文件, 这对于用户来说不方便,但是系统可以更快地处理二进制的Plist文件,可能基于这个原因,Leopard改变了Defaults的行 为:Defaults命令会改变Plist文件为二进制格式。
   阅读更多…

第14条:理解“类对象”的用意

  Objective-C实际上是一门极其动态的语言。第11条讲解了运行期系统如何查找并调用某方法的实现代码,第12条则讲述了消息转发的原理:如果类无法立即响应某个选择子,那么就会启动消息转发流程。然而,消息的接收者究竟是何物?是对象本身吗?运行期系统如何知道某个对象的类型呢?对象类型并非在编译期就绑定好了,而是要在运行期查找。而且,还有个特殊的类型叫做id,它能指代任意的Objective-C对象类型。一般情况下,应该指明消息接收者的具体类型,这样的话,如果向其发送了无法解读的消息,那么编译器就会产生警告信息。而类型为id的对象则不然,编译器假定它能响应所有消息。
   阅读更多…

第13条:用“方法调配技术”调试“黑盒方法”

  第11条中解释过:Objective-C对象收到消息之后,究竟会调用何种方法需要在运行期才能解析出来。那你也许会问:与给定的选择子名称相对应的方法是不是也可以在运行期改变呢?没错,就是这样。若能善用此特性,则可发挥出巨大优势,因为我们既不需要源代码,也不需要通过继承子类来覆写方法就能改变这个类本身的功能。这样一来,新功能将在本类的所有实例中生效,而不是仅限于覆写了相关方法的那些子类实例。此方案经常称为“方法调配”(method swizzling)。
   阅读更多…

第12条:理解消息转发机制(2)

完整的消息转发

  如果转发算法已经来到这一步的话,那么唯一能做的就是启用完整的消息转发机制了。首先创建NSInvocation对象,把与尚未处理的那条消息有关的全部细节都封于其中。此对象包含选择子、目标(target)及参数。在触发NSInvocation对象时,“消息派发系统”(message-dispatch system)将亲自出马,把消息指派给目标对象。
  此步骤会调用下列方法来转发消息: 阅读更多…

第12条:理解消息转发机制(1)

  第11条讲解了对象的消息传递机制,并强调了其重要性。第12条则要讲解另外一个重要的问题,就是对象在收到无法解读的消息之后会发生什么情况。
  若想令类能理解某条消息,我们必须以程序码实现出对应的方法才行。但是,在编译期向类发送了其无法解读的消息并不会报错,因为在运行期可以继续向类中添加方法,所以编译器在编译时还无法确知类中到底会不会有某个方法实现。当对象接收到无法解读的消息后,就会启动“消息转发”(message forwarding)机制,程序员可经由此过程告诉对象应该如何处理未知消息。
   阅读更多…

第11条:理解objc_msgSend的作用

  在对象上调用方法是Objective-C中经常使用的功能。用Objective-C的术语来说,这叫做“传递消息”(pass a   message)。消息有“名称”(name)或“选择子”(selector),可以接受参数,而且可能还有返回值。
  由于Objective-C是C的超集,所以最好先理解C语言的函数调用方式。C语言使用“静态绑定”(static binding),也就是说,在编译期就能决定运行时所应调用的函数。以下列代码为例:
阅读更多…

第10条:在既有类中使用关联对象存放自定义数据

  有时需要在对象中存放相关信息。这时我们通常会从对象所属的类中继承一个子类,然后改用这个子类对象。然而并非所有情况下都能这么做,有时候类的实例可能是由某种机制所创建的,而开发者无法令这种机制创建出自己所写的子类实例。Objective-C中有一项强大的特性可以解决此问题,这就是“关联对象”(Associated Object)。
   阅读更多…

第9条:以“类族模式”隐藏实现细节(2)

Cocoa里的类族

  系统框架中有许多类族。大部分collection类都是类族,例如NSArray与其可变版本NSMutableArray。这样看来,实际上有两个抽象基类,一个用于不可变数组,另一个用于可变数组。尽管具备公共接口的类有两个,但仍然可以合起来算作一个类族。不可变的类定义了对所有数组都通用的方法,而可变的类则定义了那些只适用于可变数组的方法。两个类共属同一类族,这意味着二者在实现各自类型的数组时可以共用实现代码,此外,还能够把可变数组复制为不可变数组,反之亦然。
   阅读更多…

第9条:以“类族模式”隐藏实现细节(1)

  “类族”(class cluster)是一种很有用的模式(pattern),可以隐藏“抽象基类”(abstract base class)背后的实现细节。Objective-C的系统框架中普遍使用此模式。比如,iOS的用户界面框架(user interface framework)UIKit中就有一个名为UIButton的类。想创建按钮,需要调用下面这个“类方法”(class method):

+ (UIButton*)buttonWithType:(UIButtonType)type; 

   阅读更多…

第8条:理解“对象等同性”这一概念(2)

等同性判定的执行深度

  创建等同性判定方法时,需要决定是根据整个对象来判断等同性,还是仅根据其中几个字段来判断。NSArray的检测方式为先看两个数组所含对象个数是否相同,若相同,则在每个对应位置的两个对象身上调用其“isEqual:”方法。如果对应位置上的对象均相等,那么这两个数组就相等,这叫做“深度等同性判定”(deep equality)。不过有时候无须将所有数据逐个比较,只根据其中部分数据即可判明二者是否等同。
   阅读更多…