Retain Count

  • 引用计数,表示当前有多少个对象对该对象引用

  • 苹果官方不推荐跟踪retainCount,因为一对象在真正执行中,可能会被某一个框架引用,也有可能会被框架的框架引用,造成retainCount和预期的不同

小测试

Q 定义NSString *str = @"hello world",问str的retainCount是多少
A 32位的系统返回最大的32位整数,64位返回最大的64位整数
  • 在OC中,如果直接使用 @"hello world" 来定义字符串,编译后会被保存在静态区,而且如果出现相同内容的字符串,所有的字符串本质上都保存在一个位置

ARC

  • 自动引用计数

  • 编译器会在会自动判断并在恰当的位置调整对象的引用计数

  • ARC模式中不允许出现retainreleaseautorelease

MRC

  • 手动引用计数

  • 需要程序员手动管理引用计数器,如果管理不当会造成内存泄漏

开发原则

  • 谁申请,谁释放,适用于面向对象开发的原则

  • 如果有alloccopyretain需要做对应的release

  • 如果有copyretain(在ARC中就是strong)的属性,需要在dealloc中进行释放

dealloc

- (void)dealloc {
   [_name release];
   [super dealloc];
}

重写属性的setter方法

setter(MRC)

- (void)setName:(NSString *)name {
   // 首先判断name和_name是否相等
   if (_name != name) {
       // 释放旧值
       [_name release];
       _name = name;
       // retain新值
       [_name retain];
   }
}

_name 与 self.name

  • 给属性设置数值的时候,使用self.name,可以调用系统默认的setter方法,保证retain是正确的

    • 但有特例

      • 第一次给属性内容设置数值的时候,苹果建议使用_name

      • 场景:loadViewviewDidLoad,前提是没有写懒加载方法

    • 在dealloc方法中,建议使用[_name release];,可以看清楚平衡关系`

      • 当然,也可以使用self.name = nil;这样会调用setter方法,但效率略低
  • 使用_name的场景,通常是初始化,或者销毁