这是我参与8月更文挑战的第12天,活动详情查看:8月更文挑战
引用计数器
OC语言使用引用计数来管理内存,每一个对象都有一个可以递增递减的计数器,如果引用这个对象,那么这个对象的引用计数递增,如果不用了,那么这个对象引用计数递减,直到引用计数为0,这个对象就可以销毁了
引用计数器的作用
- 表示对象被引用的次数
- 查看某对象的引用计数调用
- (NSUInteger)retainCount - 当使用
alloc、new、copy创建一个对象时,对象的引用计数器默认为1 - 当没有任何人使用这个对象时,系统才会回收这个对象
- 当对象的引用计数器为0时,对象占用的内存才会被回收
- 如果对象的引用计数不为0,这个对象占用的内存就不可能被回收(除非整个程序已经退出)
引用计数器的原理
- 给对象发送一条
retain消息,这个对象的引用计数值+1 - 给对象发送一条
release消息,这个对象的引用计数值-1 - 给对象发送
retainCount消息,可以获得当有对象的引用计数 注:
release并不代表销毁或回收对象,仅仅是计数器-1
属性存取方法中的内存管理(retain、copy、assign)
readonly: 只会生成getter方法readwrite:既会生成getter也会生成setter方法,默认什么不写就是readwritegetter:可以给生成的getter方法起一个名字setter:可以给生成的setter方法起一个名字retain: 会自动帮我们生成setter方法内存管理的代码assign:不会帮我们生成setter方法内存管理的代码,仅仅只会生成普通的getter/setter方法,默认什么都不写就是assignnonatomic:多线程中使用,性能低(默认)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方法中调用其他方法 - 一旦对象被回收了,它占的内存就不再可用
- 不直接调用