self.property 和 _property

一、self.property访问

  1. self.property 经过oc消息派发,可以完成属性所定义的“内存管理语义”, 例如copy属性;
  2. 通过属性访问,可以设置断点调试。

二、_property直接访问实例变量

  1. _property直接访问实例变量,不经消息派发访问速度更快;
  2. 直接访问实例变量,不会触发KVO;
  3. 直接访问实例变量,不会调用设置方法,绕过了相关属性定义的“内存管理语义”,例如在ARC中,直接访问copy属性的实例变量,不会拷贝而是直接覆盖。

结论 or 争议:
在写入实例变量时,通过self.property来做;而在读取的时候,_property直接访问的方式。既可以提高读取操作速度,又能控制对属性的写入,保证相关属性的“内存管理语义”。

三、注意点

1、懒加载,必须通过获取方法来访问属性

- (NSArray *)array{
     if(!_array){
          _array = [[NSArray alloc] init];
    }
    return _array;
}

2、不要在init和dealloc中使用self.property

  在init中,进行初始化首选会调用 self = [super init](注意这里只是子类调用了父类的init方法,并不是把父类返回给子类的self,self是对象指针,super只是个标识符,跟self不是一种类型的东东,这里self是子类的对象指针,哪怕调用到了父类的init方法,父类init中的self还是指向子类的对象,因此在父类中调用到了子类的重载方法); 即子类先调用父类init方法,如果父类在init中使用了 self.property,一旦子类重写了 self.property的该方法,那么由于多态父类中调用的其实是子类的accessor方法(即self.propert方法),而此时只是在进行父类初始化,子类初始化还未完成,调用子类的accessor可能会造成崩溃。现实中更多的是某个方法被少调用一次,出现逻辑错误。

  在销毁子类对象时,首先是调用子类的dealloc,最后调用父类的dealloc(这与init相反,在ARC中不需要我们手动调用[super dealloc], 系统会在子类dealloc的最后自动调用父类dealloc)。如果在父类dealloc调用了accessor且该accessor被子类重写,就会调用到子类断点accessor。但此时子类已经释放,就会出现错误甚至崩溃。

你可能感兴趣的:(self.property 和 _property)