导言
在读《Effective Objective-C 2.0》这本书时,学习了其中的在对象内部尽量之间访问实例变量章节,将其记录。
实例变量和属性变量的使用
当在对象之外使用实例变量时,我们通过属性来访问。但当我们在对象之内使用实例变量时,有两种选择 直接访问实例变量(_name)或访问属性(self.name)。
//对象之外
Student *student = [Student alloc]init];
NSString *studentName = student.name;
//Student.m
_name = @"指尖弹灰";
self.name = @"指尖弹灰";
那么他们两者的优缺点和使用情景是什么呢?
比较
- 直接访问实例变量(_name)比通过属性访问快(self.name).
- 直接访问实例变量的内存管理语义较低
- 直接访问实例变量,不会触发KVO
- 通过属性访问可以在set/get方法中添加断点来排查错误。
使用情景及注意
-
写入实例变量时,通过setter方法(self.name = @"指尖弹灰"),读取实例变量时,通过getter方法(a = _name)。
此方法既能提高读取操作的速度,又能控制对属性的写入操作。之所以要通过setter方法来 写入实例变量,其首要原因在于,这样做能够确保相关属性的“内存管理语义”得以贯彻。但这样做需要有下面几个注意的地方
-
在初始化方法及dealloc方法中,大多数情况应该直接通过实例变量来读写数据
在初始化中通过属性访问,如果它的子类重写了setter方法,可能发生错误
在初始化方法中如果通过属性访问,可能该属性初始化完成,但该对象还未 初始化完成,发生错误。(self.name = @"指尖弹灰"; 属性name初始化完成,但self还未初始化完成)
-
在使用惰性化初始数据时,应该通过属性读取数据
惰性化初始化数据时是在getter方法中进行初始化,所以应通过属性读取数据。