OC内存管理
首先要说一下为什么要进行内存管理:由于在移动设备上每个APP所占的内存是有限的,所以当内存占用过多时,系统就会发出警告,严重时会直接导致闪退问题.这时候就需要回收一些不需要的内存空间.在栈区的内存系统会帮你自动回收,但是你自己在堆区申请的空间需要你自己销毁,而且在你回收栈区指针的同时如果没有将指针指向的堆区内存存放的内容释放,会导致内存的泄露.
引用计数器:每个OC对象都有自己的引用计数器,是一个无符号的整数表示对象被引用的次数(也可以说正在由多少东西使用这个对象).对象被创建(即初始化对象)使用allco开辟堆区空间存放时,计数器为1,每个alloc和retain(计数+)都需要有与之对应的release(计数-1)来释放不再使用的对象.对象的内部有专门的4个字节的存储空间来存放引用计数器.(引用计数器可以使用方法retainCount来打印).其作用:是判断对象要不要回收的唯一依据就是retainCount是否为)0,若不为0,则内存还存在,对象的(retainCount)在由1到0的变化过程中即被销毁的过程(其实打印的话是不会打印出0的)系统会自动调用dealloc方法(下面会做出介绍).
dealloc就像是对象的"遗言",对象被销毁是,系统自动像对象发送一条dealloc消息,一般来说都会重写dealloc方法,在这里释放资源.一旦重写dealloc方法,就必须调用[super dealloc]并放在代码的最后部分.而dealloc是系统在对象被销毁时自动调用的,不能手动调用!一旦对象被回收,他的内存也不可再用,否则会导致野指针异常!(野指针:即访问了一块不属于你的内存)
内存管理的四个原则
原则1:凡是出现alloc,retain,copy的地方,都要有对应的release或者autorelease与之对应,保证对象用完之后能够被及时的销毁;
原则2:建类必备dealloc,凡是有属性被修饰成retain或者copy的,都要在dealloc里release一次防止外界使用属性赋值之后最后一份释放不掉;
原则3:便利构造器内应自带autorelease;
原则4:谁污染,谁处理,凡是你自己alloc,retain,copy的你就得有对应的release或者 autorelease,不是你干的你就不用管
内存管理代码规范
一,数据类型的直接赋值
-(void)setAge:(int)age
{
_age = age;
}
二OC对象类型
-(void)setStudent:(Student * )student
{
if(student != _student){//先判断进来的是否是新对象,旧对象不做处理
[_student release];//先对旧对象释放,防止就对象没有完全释放
_student = [student retain];//对新对象retain一次
}
}
三,dealloc方法的代码规范
(1)[super dealloc]一定放最后
(2)对self所拥有的其他对象做一次release操作
-(void)dealloc
{
[_student release];
[super dealloc];
}
@property的参数(retain assign(默认),copy)
属性的特性:
第一大类特性:读写特性
readWrite即生成setter ,也生成getter
readonly只生成getter
@property(readonly) NSString * name;
setter = ,getter = ,用于控制生成的setter方法和getter方法的方法名
第二大类特性:原子性特性
非原子性特性:nonatomic不保证在多线程环境下访问实例变量的安全性
原子性特性: atomic(默认)保证在多线程环境下访问实例变量是安全的,因为会加一把线程锁
第三大类特性:setter语义特性
用于控制生成的setter方法的内部实现细节
assgin,通常适用于基本类型,setter方法中就是直接赋值的
retain,适用于所有的对象类型,setter方法中会自动生成内存优化的代码
copy,仅适用于接受过NSCoping协议的类的对象才适用.
属性的实现
name = _name的含义,属性name生成的setter和getter实现中在操作_name这个实例变量
会先检查有没有该实例变量,如果没有,会自动生成一个
@synthesizename = _name;
@synthesizename = abc;
从6.0之后的版本,@synthesize也可以不用写,编译器会自动生成,
但是默认生成的属性实现中,是操作与属性名同名加下划线的实例变量
实例变量也可以不写,不写会自动生成,但是生成的是[私有的],子类不可以直接访问
自动释放池的工作原理:
当对一个对象发送autorelease消息,就会把这个对象扔到离他最近的释放池中,当这个池销毁的时候会把池中所有的对象逐一发送一次release,进池出池的过程和栈一样,遵循先进后出的原则,先进池的对象,池销毁后release