每个对象内部都有一个4个字节的存储空间存储引用计数器。
当用alloc,new,copy,创建一个对象时,新对象的引用计数器默认为1。
当给对象发送一条 retain消息,引用计数器+1
当给对象发送一条release消息,引用计数器-1
当给对象发送一条retainCount消息,反对当前引用计数器的值(NSUInteger)
非ARC
对象的销毁
*当引用计数器的值为0时被销毁,内存被回收
*当对象被销毁时,系统想对象发送一条dealloc消息(即调用类中的dealloc方法)
*一般会重写dealloc方法,在该方法里释放相关资源
*一旦重写了dealloc方法,一定要调用[super dealloc];并且要放在最后调用;
*对象不要直接调用dealloc方法
*一旦对象被回收了,它占用的内存就不可用,否则会造成野指针错误;
retain方法返回的是对象本身:
People *p = [[People alloc] init]; //此时引用计数器为1 p = [p retain]; //此时引用计数器为2
野指针:指向僵尸对象(不可用内存)的指针
错误:
EXC_BAD_ACCESS:访问了一块坏内存(已经被回收)已经不可用的内存,野指针错误。
OC中不存在空指针错误,给空指针发消息不报错.
可以在引用计数器为0后,给对象赋值nil可避免发生野指针错误。
内存管理的代码规范
1.只要调用了alloc,必须有release(autorelease)
2.set方法的代码规范
*基本数据类型:直接赋值
_age = age;
*OC对象类型
1 //先判断是不是新传进来的对象 2 if (car != _car) { 3 //1.对旧对象做一次release 4 [_car release]; 5 //对新对象做一次retain 6 _car = [car retain]; 7 }
3.dealloc方法的代码实现
*一定要调用[super dealloc];且放在最后
*对self(当前对象)所拥有的其他对象做一次release
@property参数
1.内存管理的相关参数
retain:release旧值 retain新值(适用于OC对象类型)
assign:直接赋值(默认,适用于非OC对象类型)
copy:release旧值,copy新值
2.是否要生成set方法:
readwrite:同时生成setter和getter的声明和实现(默认)
readonly:只会生成getter的声明和实现
3.多线程管理:
nonatomic:性能高 (默认)
atomic:性能低
4.setter和getter方法的名称
setter:决定了set方法的名称,一定要用冒号(因为需要传入参数)
getter:决定了get方法的名称(一般用于BOOL类型)
1.@class的作用:
仅仅告诉编译器某个名称是一个类
2.开发中引用一个类的规范
1>在.h文件中用@class来声明类
2>在.m文件中用#import来包含这个类的所有东西
3两端循环引用的解决方案
1>一端用retain
2>一端用assign