ARC在OC里面个人感觉又是一个高大上的牛词,在前面Objective-C中的内存管理部分提到了ARC内存管理机制,ARC是Automatic Reference Counting—自动引用计数。有自动引用计数,那么就得有手动引用计数MRC(Mannul Reference Counting),前面已经提到过了MRC。那么在ARC模式下是不是意味着我们就可以一点也不用进行内存管理的呢?并不是这样的,我们还需要代码进行内存的管理。下面会结合着代码把OC中的ARC机制做一个详细的总结(欢迎大家批评指针,转载请注明出处 )。
在ARC机制下是少不了下面这些东西的:
1.关键字 __strong 默认值,表示只要有强引用指针指向该变量,则该变量会一直存在。
2.关键字__weak 弱引用,表示若没有任何强引用指针指向该变量,会自动将变量的值置为空,即nil状态。
3.关键字 __autoreleasing 用于标示自动释放的变量
4.__unsafe_unretained 不安全的弱引用,若没有任何强引用指针指向该变量,不会自动设为空,会成为野指针。
关于Weak和Strong,看下图吧:
第一次接触ARC的小伙伴们看到上面的概念可能会一头雾水,上面说的是个啥?都是哪跟哪?不用着急,下面会有实例代码,结合着实例代码,然后再做一个总结,你就会有种豁然开朗的感觉。你就会明白,哦,原来ARC是这么一回事。好啦,废话少说,用代码讲东西才是王道,代码走起。(为了方便我们观察内存的释放情况,可以设置断点来单步运行)
为了做测试使用,我们建一个测试类,并重写dealloc方法来观察内存的释放情况,测试类如下;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
#import @interface TestClass : NSObject @property(nonatomic, strong) NSString *name; @end #import "TestClass.h" @implementation TestClass //dealloc在对象释放是回调用 -(void)dealloc { NSLog(@"%@,对象被释放啦!", _name); } @end |
一.__strong: 强引用,是ARC中变量声明的默认值,用大白话讲就是你手动分配的堆内存,如果没有指针指向这块内存,那么这块内存就会被回收
1.当声明变量为强引用时,对象的指针出栈时,如果该指针指向的内存空间没有别的指针指向他,就自动掉用dealloc方法释放堆内存测试代码如下:
1 2 3 4 5 6 7 8 9 10 11 |
//情况1.当指向内存的指针在出栈时,内存被释放 void strongTest1() { //测试用的代码块 { //默认为强引用的变量 TestClass *obj1 = [TestClass new]; obj1.name = @"obj1"; } NSLog(@"在出上面的大括号时,指针变量被释放,堆分配的内存也会别立即释放"); } |
代码运行结果:
1 2 |
2014-08-13 19:25:52.378 ARCDemo[4345:303] obj1,对象被释放啦! 2014-08-13 19:25:52.380 ARCDemo[4345:303] 在出上面的大括号时,指针变量被释放,堆分配的内存也会别立即释放 |
代码说明:从运行结果来看,出代码块后我们定于的指针变量会随着我们代码块的结束而释放,就没有指针指向我们分配的堆内存了,以为默认为strong,所以在ARC机制下会立即调用dealloc来释放堆内存。
2.给对象指针重写分配内存的情况,代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
//情况2.当对象指针 指向其他内存时,原有的内存若没有指针指向他,就会被立即释放 void strongTest2() { { TestClass * obj1 = [TestClass new]; obj1.name = @"obj1"; //给已经分配内存的指针在分配新的内存 obj1 = [TestClass new]; NSLog(@"经过上面一步会释放第一次分配的堆内存!"); obj1.name = @"obj1_new"; } NSLog(@"出大括号回释放第二次分配的内存"); } |
代码运行结果:
1 2 3 4 |
2014-08-13 19:30:38.455 ARCDemo[4356:303] obj1,对象被释放啦! 2014-08-13 19:30:38.456 ARCDemo[4356:303] 经过上面一步会释放第一次分配的堆内存! 2014-08-13 19:30:38.457 ARCDemo[4356:303] obj1_new,对象被释放啦! 2014-08-13 19:30:38.457 ARCDemo[4356:303] 出大括号回释放第二次分配的内存 |
代码说明:我们先给strong类型的对象指针分配内存空间,然后再次分配内存空间,在第二次分配空间的时候,就没有对象指针指向原有的内存空间,所以在第二次分配空间之后就会把原有的内存空间给释放掉,在出代码块的时候,对象指针也会随着栈内存的释放而释放掉,也没有对象指针指向第二次分配的内存了,所以会被释放掉。
3.把对象指针置为空时,分配的堆内存会立即被释放掉。相应的代码如下:
1 2 3 4 style="font-size: 13px !important; line-height: 15px !important;"> 1 2 3 4 |