Effective Objective-C 2.0 笔记2
二、对象、消息和运行时
①、直接访问实例变量还是使用属性方法访问?
(1)、直接访问实例变量速度快,因为不经过Objective-C的方法分发系统,而是直接用的变量在内存中的存储地址。
(2)、同时,直接访问会忽视属性property的内存管理语法。例如,如果一个属性定义为copy,直接访问就会忽视copy,不会产生一个复制。
(3)、直接访问实例变量,不会出发KVO通知。因为KVO是改写了别观察属性的set方法,在变化前和变化后,发送通知。具体文章可以猛击这里。一个妥协的解决方案是,读数据时采用直接访问方式,写数据时采用属性方法setXXX方式。这样,既可以保证读取速度,又能保证写数据时的内存管理策略的正确性。
(4)、在initializers和dealloc等方法中,用直接访问的方式来读、写实例变量。
(5)、当属性是懒加载模式时,需要用属性方法getXXX来读取。
1 | - (NSString *)name { |
②、对象相等,必须有相同的hash值。拥有相同hash值的对象,不必相等。
③、类簇模式是抽象工厂模式的一种。
④、消息转发
(1)、编译器会把方法转成一个标准的C函数void objc_msgSend(id self,SEL cmd,…),其中第一个参数是接收者,第二个参数是selector,即方法。
(2)、方法调用的过程:首先,会在类的方法列表中查找方法。如果找不到,则从继承链上的父类方法中查找。如果还找不到,则进行消息转发。
(3)、objc_msgSend会缓存已经用过的方法,以方便以后快速调用。即使如此缓存,还是比静态绑定慢。实际情况中,消息分发系统不是应用速度的瓶颈所在。
(4)、消息转发示意图
其中每一步消息接收者都有一次机会来处理消息。越往后,所花费的开销就越大。