第七条 :在对象内部尽量直接访问实例变量
在对象之外访问实例变量是,总是应该通过属性来做,那么在对象内部访问实例变量时又该如何呢?
除了几种特殊情况外,在对象内部读取实例变量的时候采用直接访问的形式,而在设置实例变量的时候通过属性来做。
使用点语法与直接访问实例变量的几个区别:
由于不经过Objective-C的“方法派发”(method dispatch)步骤,所以直接访问实例变量的速度当然比较快。在这种情况下,编译器所生成的代码会直接访问保存对象实例的那块内存。
直接访问实例变量时,不会调用其“设置方法”,这就绕过了为设置相关属性所定义的“内存管理语义”。
比如说,ARC下直接访问一个声明为copy的属性,那么并不会拷贝该属性,只会保留新值并释放旧值。
如果直接访问实例变量,那么不会触发“键值观察”(key-Value Observing,KVO)通知。这样做是否会产生问题,还取决于具体的对象行为。
通过属性来访问有助于排查与之相关的错误,因为可以给“获取方法”和/或“设置方法”中新增“断点”(breakpoint),监控该属性的调用者及其访问时机。
有一种合理的折中方案,就是:在写入实例变量时,通过其“设置方法”来做,而在读取该实例变量时,则直接访问。此办法既能提高读取操作的速度,又能控制对属性的写入操作。之所以要通过“设置方法”来写入实例变量,其首要原因在于,这样能够确保相关属性的“内存管理语义”得以贯彻。
但是选用这种做法需要注意几个问题:
第一个问题:在初始化方法中应该如何设置属性值。这种情况下总是应该直接访问实例变量,因为子类可能会“覆写”(override)设置方法。
另一个要注意的问题是:“惰性初始化”(lay initialization)。在这种情况下,必须通过“获取方法”来访问属性,否则,实例变量就永远不会初始化。
若没有调用“获取方法”就直接访问实例变量,则会看到尚未设置好的属性,所以说,如果使用了“懒加载”技术,那么必须通过存取方法来访问属性。
要点:
1.在对象内部读取数据时,应该通过实例变量来读,而写入数据时,则应通过属性来写
2.在初始化方法及delloc方法中,总是应该直接通过实例变量来读写数据
3.有时会使用懒加载初始化技术配置某份数据,这种情况下,需要通过属性来读取数据