之前一片文章中我们介绍了OC中的两个关键字 @property 和 @synthesize 的使用的使用,今天我们来看一下OC中数组对象在是如何处理对象元素的引用计数问题的,同时介绍一下自动释放池的相关概念
一、数组对象是如何处理对象元素的引用计数问题
1 // 2 // main.m 3 // 26_NSArrayMemeryManager 4 // 5 // Created by jiangwei on 14-10-12. 6 // Copyright (c) 2014年 jiangwei. All rights reserved. 7 // 8 9 #import <Foundation/Foundation.h> 10 11 #import "Dog.h" 12 13 int main(int argc, const charchar * argv[]) { 14 15 Dog *dog1 = [[Dog alloc] init]; 16 Dog *dog2 = [[Dog alloc] init]; 17 18 NSMutableArray *array = [[NSMutableArray alloc] init]; 19 20 //数组会对每一个元素retain 21 [array addObject:dog1]; //dog1计数=2 22 [array addObject:dog2]; //dog2计数=2 23 24 [dog1 release]; 25 [dog2 release]; 26 27 //当数组销毁的时候,会将所有的元素release 28 [array release];//数组销毁 29 30 //当数组移除所有的元素的时候,会讲所有的元素release 31 [array removeAllObjects]; 32 33 return 0; 34 }
我们定义了Dog类,然后定义了NSMutableArray数组存放两个Dog对象,OC中在将对象放到数组中的时候,会自动调用retain方法,当数组对象本身被销毁的时候,会调用所有元素的release方法,当移除数组中所有的元素的时候,会调用元素的release方法
二、自动释放池的概念
1 // 2 // main.m 3 // 27_AutoReleasePool 4 // 5 // Created by jiangwei on 14-10-13. 6 // Copyright (c) 2014年 jiangwei. All rights reserved. 7 // 8 9 #import <Foundation/Foundation.h> 10 11 #import "Dog.h" 12 13 int main(int argc, const charchar * argv[]) { 14 15 /* 16 //创建一个自动释放池 17 //有作用域的问题,在{}中定义的东西外部是不能访问的,这点和NSAutoreleasePool有区别的 18 @autoreleasepool {//等价于[[NSAutoreleasePool alloc] init] 19 20 Dog *dog2 = [[Dog alloc] init]; 21 [dog2 retain]; 22 23 }//等价于[pool release] 24 25 //创建一个自动释放池 26 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 27 28 Dog *dog1 = [[Dog alloc] init];//计数:1 29 30 //将dog1对象加入到自动释放池中,却别于之前的release方法 31 //加入到自动释放池中之后,不是代表我们不需要管理引用了,只是自动释放池自动会调用一次release 32 //当自动释放池销毁的时候,释放池会对池中每一个对象调用一次release 33 [dog1 autorelease]; 34 NSLog(@"dog1计数:%ld",dog1.retainCount); 35 36 //销毁自动释放池 37 //这时候会调用dog1的release方法,dog1对象就被销毁了 38 [pool release]; 39 */ 40 41 //自动释放池的嵌套 42 NSAutoreleasePool *pool1 = [[NSAutoreleasePool alloc] init]; 43 44 //添加我们的代码 45 //dog1放到了pool1中 46 Dog *dog1 = [[Dog alloc] init]; 47 [dog1 autorelease]; 48 49 //自动释放池的嵌套 50 NSAutoreleasePool *pool2 = [[NSAutoreleasePool alloc] init]; 51 52 //dog2放到了pool2中 53 Dog *dog2 = [[Dog alloc] init]; 54 [dog2 autorelease]; 55 56 //pool2销毁了 57 [pool2 autorelease]; 58 59 //pool1销毁了 60 [pool1 release]; 61 62 63 //下面的代码就是有问题的 64 //[person setDog:[[Dog alloc] init]; 65 //正确的写法 66 //Dog *dogs = [[[Dog alloc] init] autorelease]; 67 68 69 70 return 0; 71 }
我们在之前的文章中,定义一个对象的时候都会产生一个自动释放池,然后在释放池中编写我们的代码,自动释放池是系统提供的一种帮助我们去管理对象的引用计数问题。但是有时候代码必须在{...}中编写,这样的话就会产生作用域的问题,就是在{...}中定义的变量,在{...}外面不能使用。所以OC中就有了另外的一种方式:NSAutoreleasePool这个类。
这种自动释放池可以实现嵌套
1 NSAutoreleasePool *pool1 = [[NSAutoreleasePool alloc] init]; 2 3 //write code... 4 5 6 7 //pool1销毁了 8 9 [pool1 release];
上面的代码就相当于建立了一个自动释放池pool1,但是在这个中间的代码,如果要加入到这个池中,必须调用autorelease方法:
1 //dog1放到了pool1中 2 Dog *dog1 = [[Dog alloc] init]; 3 [dog1 autorelease];
而且,这样定义一个池子还可以嵌套使用,直接看上面的例子代码,这样这个自动释放池我们就可以控制了。比系统提供的自动释放池可操作的地方很多。
下面就直接对比一下:
1 NSAutoreleasePool *pool1 = [[NSAutoreleasePool alloc] init]; 2 { 3 [pool1 release];//这行代码就相当于系统自动释放池的 4 }
这样就好理解了吧
总结
这一篇文章主要介绍了OC中数组对象操作元素对象的时候需要处理的引用问题,以及我们可以自定义一个自动释放池,这种方式比系统提供的自动释放池方便,可操作性强。
时间: 2024-10-25 01:14:06