本文会继续深刻学习OC内存管理,内容主要参考iOS高级编程,Objective-C基础教程,疯狂iOS讲义,是我学习内存管理的笔记objective-c
MRC
>(Mannul Reference Counting)ARC
>(Automatic Reference Count)GC
>(Garbage Collection)因为iOS系统不支持垃圾回收,因此咱们在iOS开发中只能使用MRC和ARC来进行内存管理,本文再也不介绍Objective-C中的垃圾回收机制,可是此处注意Objective-C中是存在垃圾回收机制的
内存泄露
:再也不须要的对象没有释放编程
引发的问题
:程序的内存占有量不断增长,最终会被耗尽致使程序崩溃野指针
:没有进行初始化得指针函数
引发的问题
:浪费内存资源,若是调用程序会出现未知的结果,甚至致使程序崩溃学习
悬空指针
:一个指针指向一个被销毁的对象指针
引发的问题
:调用悬空指针指向的属性或者方法时,程序会出现未知的结果,甚至致使程序崩溃调试
僵尸对象
:过分释放的对象code
引发的问题
:对象
MRC
>(Mannul Reference Counting)引用计数
:Objective-C中引入了引用计数这一机制来跟踪并处理对象的生命周期,继承
管理方式
:每一个对象都有一个与之关联的整数,这个整数被称为引用计数,在Objective-C中,经过不一样的方法能够对引用计数进行操做,具体的处理以下表:教程
对象操做 | Objective-C方法 | 对应的操做结果 |
---|---|---|
生成并持有对象 | alloc , new , copy ,mutableCopy 等方法 |
生成对象并设置引用计数 =1 |
持有对象 | reatain 方法 |
使引用计数 +1 |
释放对象 | release 方法 |
使引用计数 -1 |
废弃对象 | dealloc 方法---系统自动调用 |
引用计数 =0 时调用 |
关于delloc
方法:dealloc方法继承自NSObject
,所以全部的对象都具备此方法,当一个对象的引用计数为0时,也就意味着没有任何程序须要此对象,系统会回收该对象所占用的内存,在系统销毁对象以前,会自动调用该对象的dealloc方法来执行一些回收操做,若是该对象还持有其余对象的引用,咱们必须重写dealloc方法来释放该对象引用的其余对象(一般就是使用该对象的release方法)
引用计数机制回收对象的说明
:若是一个对象的引用计数为0,则代表程序已经再也不须要它,这时系统会自动回收该对象所占内存,相反,若是一个对象的引用计数不为0,系统就不该该回收,也不会回收它所占的内存
关于retainCount方法
:Objective-C提供了retainCount方法来返回一个对象当前的引用计数
如何重写dealloc方法
:
- (void)dealloc { // 处理该对象的其余引用(经过release方法) /** 回调父类的dealloc方法 */ [super dealloc]; }
alloc
+alloc +allocWithZone: class_createInstance //此方法能够经过objc4中的runtime/objc-runtime-new.mm确认 calloc // 分配内存块
retainCount
-retainCount __CFDoExternRefOperation // 此函数根据retain,retainCount,release操做进行分发,调用__CFBasicHashXXX方法 CFBasicHashGetCountOfKey
retain
-retain __CFDoExternRefOperation CFBasicHashAddValue
release
-release __CFDoExternRefOperation CFBasicHashRemoveValue // 当此函数返回0时, -release调用dealloc方法
1.1 使用alloc
new
copy
mutableCopy
建立的对象只能本身持有
id obj1 = [[NSObject alloc] init]; id obj2 = [NSObject new]; id obj3 = [NSObject copy]; id obj4 = [NSObject mutableCopy];
1.2 使用以上名称的开头的方法也意味着本身生成并持有对象
alloc
NewObject
new
NewObject
copy
NewObject
mutableCopy
NewObject
2.1 非alloc
new
copy
mutableCopy
生成的对象,变量obj自己不持有该对象
id obj1 = [NSMutableArray array]; id obj2 = [NSDictionary dictionary];
2.2 经过retain方法,非经过alloc
new
copy
mutableCopy
生成的对象,能够成为本身持有的对象
id obj = [NSMutableArray array]; [obj retain];
3.1 释放经过alloc
new
copy
mutableCopy
生成的对象,一旦不在须要,务必要使用release方法释放
id obj = [[NSObject alloc] init]; [obj release];
3.2 用retain方法持有的非本身生成的对象,一旦再也不须要,也必定要使用release释放
id obj = [NSMutableArray array]; [obj retain]; // 经过retain方法持有对象 [obj release]; // 在不须要时也要经过release方法释放对象
3.3 用某个方法生成对象,并将其做为方法的返回值,这时咱们该如何处理
3.3.1 经过alloc
new
copy
mutableCopy
或其余符合命名规则的方法生成的对象,只须要原封不动的返回就能让调用方也持有该对象
- (id)allocObject { id obj = [[NSObject alloc] init]; return obj; } - (id)allocObjectWithObject:(id)obj { id object = [obj allocObject]; return object; }
3.3.2 若是持有非本身生成的对象,例如[NSMutableArray array]生成的对象,咱们要使用autorelease方法释放
注:命名规则
:用来取得谁都不持有的对象的方法名不能以alloc
new
copy
mutableCopy
开头
- (id)object { id obj = [NSMutableArray array]; [obj autorelease]; return obj; }
3.3.3 autorelease
方法:提供了这样的功能,使对象在超出指定的生存范围时自动并正确释放(调用release方法)
4.1 经过alloc
new
copy
mutableCopy
方法或者经过retain方法持有的对象,一旦再也不须要时,必须进行释放,除此以外其余方法得到的对象绝对不能释放,一旦释放会形成程序崩溃
4.2 本身持有的对象释放后再次释放,形成僵死对象,引发程序崩溃或在访问废弃的对象时崩溃
id obj = [[NSObject alloc] init]; [obj release]; [obj release]; // 再次释放