结合之前的学习笔记以及参考《Objective-C编程全解(第三版)》,对Objective-C知识点进行梳理总结。知识点一直在变,只是作为参考,以苹果官方文档为准~
十五、内存管理相关知识(一)
1、内存管理的必要性
(1)若程序没能妥善管理内存,运行过程中不但不能释放不再使用的内存,而且还会不停的分配内存,这样内存的占用越来越多,程序速度也会越来越慢,最后甚至会因为内存的耗尽而崩溃
(2)内存管理范围:任何继承了NSObject的对象,对基本数据类型无效(系统会自动回收);
相关名词:这几个名词都要重点结合程序理解!!!
(1)内存泄露:程序未能释放已经不再使用的内存;
(2)僵尸对象:对象被销毁,不能再使用,不能给它发送任何消息;
(3)野指针(垂悬指针):指向僵尸对象的指针,给野指针发消息会造成不可控后果;
(4)空指针:没有指向任何对象的指针,给其发消息不会产生任何行为;
2、引用计数:跟踪每个对象被引用的次数,当对象的引用次数为0时,系统会释放这个对象所占用的内存。
简言之就是指程序中到底有多少个地方需要访问这个对象;
3、基于引用计数的内存管理相关方法
(1)alloc:引用计数器初始值为1
(2)retain:引用计数器+1,返回经过+1后的当前实例对象;
- (id)retain;
(3)release:引用计数器-1,不是释放内存方法!!!
- (oneway void)release;
(4)retainCount:获取引用计数器的值
(5)dealloc:实例对象被销毁前,系统自动调用;引用计数为0时,自动调用;
MRC手动引用计数
4、dealloc方法的重写
release只是释放对这个对象的所有权,真正释放对象所占的内存的是dealloc方法。
释放一个类的实例对象时,为了彻底释放该实例对象所保持的所有对象的所有权,需要为该类重写dealloc方法,在其中释放已经分配的资源,放弃实例对象的所有权。
- (void)dealloc {
//通过release方法放弃子类中所有实例变量的所有权,其它用于释放前的善后操作也写在此处,不可直接dealloc,release到0自动调用dealloc
[super dealloc]; //这样内存的释放会从子类一直向上直到NSObject
}
注意:不要“善后工作”结束后,一定要调用父类的dealloc方法,这样才能使这个对象彻底被释放掉
5、setter方法重写
由于经常会出现例如
p.book = book1;
p.book = book2;再次赋值的情况,或者自我赋值的情况,因此重写并完善setter方法
(1) 基本类型
- (void)setObj:(NSInteger)obj { _obj = obj;
}
(2) OC对象类型两种方法
- (void)setObj:(id)obj { [obj retain];
[_obj release];
_obj = obj;
}
- (void)setObj:(id)obj {
//判断是否是自我赋值
if (_obj != obj)
{
//对原对象作一次release,释放对旧车的所有权
[_obj release];
//对新对象作一次retain,并赋值给当前对象
_obj = [obj retain];
}
}
6、关于property与内存管理相关的参数,已经在
“Objective-C(四、属性声明与功能,点语法)——iOS开发基础”
http://blog.csdn.net/zsk_zane/article/details/46648917
一文中详细说明了,现在可以结合本文相关的内存管理的知识进行理解了。
7、循环引用(循环保持retain cycle)
A,B相互引用,按规则,只有释放B以后才能释放A(否则A引用计数为1无法释放),同样B也相同情况,大致两个对象都不会被释放,造成内存泄露,只有打破循环引用关系才能够释放内存。
解决:一端用retain,一端用assign
A.h 中
@property (nonatomic, retain) A *a;
B.h 中
@property (nonatomic, assign) B *b;
这是内存管理知识的第一部分
下一部分关于ARC,自动释放池等等知识点,这几天会挑空整理,在下一篇章中呈现~晚安啦~