iOS中内存管理(引用计数器)

1,047 阅读3分钟

这是我参与8月更文挑战的第12天,活动详情查看:8月更文挑战

引用计数器

OC语言使用引用计数来管理内存,每一个对象都有一个可以递增递减的计数器,如果引用这个对象,那么这个对象的引用计数递增,如果不用了,那么这个对象引用计数递减,直到引用计数为0,这个对象就可以销毁了


引用计数器的作用

  • 表示对象被引用的次数
  • 查看某对象的引用计数调用- (NSUInteger)retainCount
  • 当使用allocnewcopy创建一个对象时,对象的引用计数器默认为1
  • 当没有任何人使用这个对象时,系统才会回收这个对象
  • 当对象的引用计数器为0时,对象占用的内存才会被回收
  • 如果对象的引用计数不为0,这个对象占用的内存就不可能被回收(除非整个程序已经退出)

引用计数器的原理

  • 给对象发送一条retain消息,这个对象的引用计数值+1
  • 给对象发送一条release消息,这个对象的引用计数值-1
  • 给对象发送retainCount消息,可以获得当有对象的引用计数 注:
    release并不代表销毁或回收对象,仅仅是计数器-1

属性存取方法中的内存管理(retain、copy、assign)

  • readonly: 只会生成getter方法
  • readwrite:既会生成getter也会生成setter方法,默认什么不写就是readwrite
  • getter:可以给生成的getter方法起一个名字
  • setter:可以给生成的setter方法起一个名字
  • retain: 会自动帮我们生成setter方法内存管理的代码
  • assign:不会帮我们生成setter方法内存管理的代码,仅仅只会生成普通的getter/setter方法,默认什么都不写就是assign
  • nonatomic:多线程中使用,性能低(默认)
  • atomic:多线程中使用,性能高
- (void)setName:(NSString *)name{
    if (_name != name) {//先判断传进来的是不是新对象
        [_name release];  //把_name以前的对象release
        _name = [name retain]; //把name对象的地址赋给_name,这时name和_name共同指向同一个对象
    }
}

- (void)setName:(NSString *)name{
    if (_name != name) {
        [_name release];//把_name以前的对象release
        _name = [name copy];//把name对象的地址拷贝一份给_name
    }
}
-(void)setName:(NSString *)name{
        _name = name;    //直接赋值
}

dealloc方法

  • 当一个对象的引用计数器值为0的时候,这个对象即将被释放,其占用的内存被系统收回
  • 对象即将被销毁时系统会自动给对象发送一条dealloc的消息(因此,从dealloc方法有没有被调用就可以判断出对象是否被销毁)
  • dealloc方法重写
    • 一般重写dealloc方法,在这里释放相关资源(移除监听者、移除coreFoundation对象等等)
    • 在MRC下,一旦重写dealloc方法,就必须调用[super dealloc],并且放在最后调用
  • 使用注意
    • 不直接调用dealloc
    • 不要在dealloc方法中调用其他方法
    • 一旦对象被回收了,它占的内存就不再可用

关于iOS内存管理相关知识点