内存管理
管理范围
任何继承NSObject的对象
只有OC对象才需要进行内存管理的本质原理
1.OC对象在堆中
2.非OC对象一般放在栈
堆
由操作系统自动分配释放存放函数值局部变量的值等
栈
一般要又程序猿分配释放,若程序员不释放,程序结束时由OS回收(目前的Xcode已经要有ARC)
引用计数器
每个OC对象都有自己的引用计数器,它是个整数,表示当前被多少人使用
当引用计数器为0时,系统将回收这个对象,如果引用计数器不为0,那么在这个运行过程中,将无法对这个对象释放
引用计数器的操作
给对象发送retain消息时,引用计数器+1
给对象发送release消息时,引用计数器-1
给对象发送retainCount消息时,可以获得当前引用计数器的值
dealloc方法
对象释放时,将调用dealloc方法,因此可以重写dealloc方法,一旦重写,必须使用[super dealloc]
并在最后调用
ARC
Automatic Reference Counting 自动引用计数
不需要程序猿管理内存,编译器会在适当的地方自动给我们添加release/retain等代码
ARC和JAVA中的垃圾回收机制不一样,JAVA的垃圾回收是系统操作的,ARC是编译器操作的
MRC
Manual Reference Counting 手动应用计数器
所有对象的内容都需要我们手动管理,需要程序猿编写release/retain等代码
内存管理原则
有加就有减:即alloc一次对应一次dealloc 一次retain对应一次/release
野指针和空指针
只要一个对象被释放,我们称该对象为僵尸对象
当一个指针指向僵尸对象时我们称为野指针
给野指针发送消息时,程序会报错
为了避免给野指针发送消息会报错,一般情况下,当一个对象被我们释放后,将这个对象的指针设置为空,OC中给空指针发送消息不错报错,
p = nil
多对象管理内存
当A对象想使用B对象时,必须对B对象进行一次retain,这样才能保证A对象存在,B对象也存在
就是这样才能保证无论何时,A对象中都可以使用B对象
A对象释放的湿乎乎,一定要对B进行一次release,这样才能保证A对象释放了,B对像也会随着释放避免内存泄漏
set方法内存管理
-(void)SetCar:(Car *)car
{
if(_car != car)
{
[_car release];
_room = [room retain];
}
}
Property修饰符
retain:会自动生成上例的set方法内存管理方法
assign:不会生成上例的set方法内存管理方法,只会生成普通的getter/setter方法(默认)
atomic:性能低
nonatomic:性能高(iOS开发)
注意:相同类型修饰符不能同时使用 getter/setter除外
不同类型修饰符可以用时使用用逗号隔开例如
@property(nonatomic,retain) Car *car
@class
引用一个类,类似#import
在.h中使用@class
在.m中使用#import
可以提高编译效率
总结
如果都在.h中使用#improt
,假如A拷贝了B,B拷贝了C,如果C被修改了,那么B和A都需要重新拷贝,如果在.h中使用@class
,而在.m中使用#improt
,如果一个文件发生了变化,只有和这个文件有直接关系的那个文件才会重新拷贝
如果在a.h中拷贝了b.h 在b.h中拷贝了a.h,会形成死循环,在.h中用@class 在.m中使用#import可以解决以上问题
循环retain
假如A对象要拥有B对象,B对象又要拥有A对象,会形成循环retain
解决方法:让乙方不要进行retain就好了