OC学习篇之---数组对象的引用计数问题和自动释放池的概念

之前一片文章中我们介绍了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中数组对象操作元素对象的时候需要处理的引用问题,以及我们可以自定义一个自动释放池,这种方式比系统提供的自动释放池方便,可操作性强。

你可能感兴趣的:(数组)