Objective-C-实例变量与属性的关系

当在一个类创建一个属性,Xcode编译器就会自动产生一个带下划线的同名实例变量;

一般来说,如果getter这个属性采用下划线的方式获取效率更高,而setter采用self.属性名更加合理。

读取实例变量的时候采用直接访问的形式,而在设置实例变量的时候通过属性来做。

直接访问实例变量时,不会调用其“设置方法”,也就是说不会不会触发“键值观测”(Key-Value Observing, KVO)通知。

 


 

第一个要注意的地方就是,在初始化方法中应该如何设置属性值。这种情况下总是应该直接访问实例变量,因为子类可能会“覆写”(override)设 置方法。假设EOCPerson有一个子类叫做EOCSmithPerson,这个子类专门表示那些姓“Smith”的人。该子类可能会覆写 lastName属性所对应的设置方法:
 

  1. - (void)setLastName:(NSString*)lastName {  
  2.     if (![lastName isEqualToString:@"Smith"]) {  
  3.         [NSException raise:NSInvalidArgumentException  
  4.                     format:@"Last name must be Smith"];  
  5.     }  
  6.     self.lastName = lastname;  

在基类EOCPerson的默认初始化方法中,可能会将姓氏设为空字符串。此时若是通过“设置方法”来做,那么调用的将会是子类的设置方法,从而抛 出异常。但是,某些情况下却又必须在初始化方法中调用设置方法:如果待初始化的实例变量声明在超类中,而我们又无法在子类中直接访问此实例变量的话,那么 就需要调用“设置方法”了。

另外一个要注意的问题是“惰性初始化”(lazy initialization)。在这种情况下,必须通过“获取方法”来访问属性,否则,实例变量就永远不会初始化。比方说,EOCPerson类也许会 用一个属性来表示人脑中的信息,这个属性所指代的对象相当复杂。由于此属性不常用,而且创建该属性的成本较高,所以,我们可能会在“获取方法”中对其执行 惰性初始化:
 

  1. - (EOCBrain*)brain {  
  2.     if (!_brain) {  
  3.         _brain = [Brain new];  
  4.     }  
  5.     return _brain;  

若没有调用“获取方法”就直接访问实例变量,则会看到尚未设置好的brain,所以说,如果使用了“惰性初始化”技术,那么必须通过存取方法来访问brain属性。

 
 
posted @ 2015-06-18 14:37  N了歌C  阅读(227)  评论(0编辑  收藏  举报