7 OC加强01
内存管理
内存的五大区
桟区:局部变量,指针作用域结束以后就会被释放
堆区:OC对象,自已申请的内存空间(free),不会自己释放.
BSS段:未初始化的全局变量,和静态变量.初始化后被释放了,存到了常量区.
常量区:已经初始化的全局变量,静态变量和常量.程序结束才会被释放.
代码段:代码.程序结束才会被释放.
堆区的内存肯定要被回收的.
iphone内存管理非常严格(40M(警告),45M(警告),120M闪退)
堆区对象不会自动释放的.
内存管理的范围:只需要管理堆区中的内存对象.
- MRC面试百分百必考
- 早期的app都是基于MRC开发的
- 大牛都是从MRC成长来的
- ARC基于MRC的(ARC是在2011年ios5上出现的)
开启MRC
1,引用计数器:各一个OC对象都有这个属性,叫做* retainCount(引用计数器) ,类型是unsigned long(8个字节),表示有多少人在使用这个对象.当retainCount为0时,这个对象就会被释放,并且 自动调动dealloc方法 *.
2,retain 对象方法,引用计数器加1,多一个人使用这个对象.
3,release 对象方法,引用计数器减1,少一个人使用这个对象.
监视对象的回收:
因为对象在回收时会自动调用dealloc方法,那就可以重写dealloc以便监测对象的回收.注意:必须在最后调用父类的dealloc方法
当dealloc方法先是执行父类的dealloc其实也是自己这个对象的一些属性
被释放,所以也证明了必须写super dealloc
- (void)dealloc{
NSLog(@"person dead");
//注意:最后一定要调用父类的dealloc
[super dealloc];
}
内存管理的原则
* 谁retain,谁release * **
野指针和僵尸对象
C中的野指针:当创建一个指针的时候,没有给指针初始化,这个指针变量的值就是垃圾纸,指向内存的一块空间
OC中的野指针:一个指针指向的对象已经被释放了(僵尸对象),这个指针就叫做野指针.这个时候可以给这个指针赋值nil,调用方法就不会出错了.
对象的回收:变量的回收指的是变量所占用的字节空间系统可以分配给别人.对象也是这样(系统把空间分配给别人之前,数据还在)
僵尸对象:一个已经被回收的对象,但是对象的数据都还在(没有被分配给其他人)
- 一旦一个对象成为僵尸对象以后,一定不能再使用这个对象了.开启僵尸对象的实时监测
开启僵尸对象检测
单个对象的内存管理
- * 内存泄露:指的对象该回收的时候没有被回收,一直在内存中,程序结束才会被释放. *
- 指针的值为nil时,通过它调用方法不会有任何反应,也不会报错,如何避免野指针报错->当一个指针为野指针的时候,又不想开启僵尸对象检测,为这个指针赋值nil.
ZLPerson *p1 = [ZLPerson new];
p1 = nil;
[p1 release];
多个对象的内存管理
- set方法内,判断是否新旧对象,做判断,旧对象不作任何处理,新对象先release旧对象,再retain新对象.
- (void)setCar:(ZLCar *)car{
//旧对象不等于新对象才要release旧对象,再retain新对象
if (_car != car) {
[_car release];
_car = [_car retain];
}
}
- 使用这个对象的对象被释放时,系统自动调用dealloc方法,在内部先释放他所用属性对象.
- (void)dealloc{
NSLog(@"%@死了",_name);
[_car release];
[super dealloc];
}
- 谁retain,谁release.
当属性类型为OC对象的时候,set方法的写法
只有当属性的类型是一个OC对象的时候(堆区),才需要管理内存.属性是其他数据类型,内存会帮你管理.堆区从低地址到高地址.
@propert参数的含义
atomic:默认值(生成set,get方法但是很安全)
nonatomic:不安全,但是效率快
assign:默认值,非对象(set方法的实现中直接赋值)
retain:对象(set方法的实现中,生成标准的MRC内存管理代码)
readwrite:默认值,读写(同时生成set,get方法)
readonly:只读(只生成get方法)
getter,setter改set,get方法名.无论什么情况都不要改setter方法的名字,当属性为BOOL类型的时候,才改getter名,且以is开头,增强代码的可读性.
注意:retain只是在set方法实现内生成标准的MRC内存管理代码,不会管dealloc,所以dealloc中的对象属性还是要release.