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

时间: 2024-10-25 01:14:06

(转载)OC学习篇之---数组对象的引用计数问题和自动释放池的概念的相关文章

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

之前一片文章中我们介绍了OC中的两个关键字@property和@synthesize的使用的使用: http://blog.csdn.net/jiangwei0910410003/article/details/41925967 今天我们来看一下OC中数组对象在是如何处理对象元素的引用计数问题的,同时介绍一下自动释放池的相关概念 一.数组对象是如何处理对象元素的引用计数问题 // // main.m // 26_NSArrayMemeryManager // // Created by jian

OC_内存管理(二)对象复制、循环引用问题、自动释放池

循环调用: 1.循环引用的问题 两个对象A.B,有可能会出现特殊情况:A中包含B的实例变量:B中也包含A的实例变量,如果这两个实例变量都是强引用(A有着B的实例变量所有权,B也有A的实例变量所有权),然后在两个对象销毁时,会出现A.B都不能正常销毁的情况.下面用代码来演示循环调用问题: ClassA的头文件Class.h代码 #import <Foundation/Foundation.h> //类的前向声明 @class ClassB; //类的前向声明与包含头文件的区别?Q: @inter

OC学习篇之---总结和学习目录

今天终于把OC的基础知识学习完了,但是这些知识只是最基础的,还有很多高级知识,这个可能需要后面慢慢的去学习才能体会到.下面就是这次学习OC的目录教程,如果大家发现有什么不正确的地方,请指正,小弟是新生,多请OC老鸟来喷~~ 1.OC学习篇之---概述 2.OC学习篇之---第一个程序HelloWorld 3.OC学习篇之---类的定义 4.OC学习篇之---类的初始化方法和点语法的使用 5.OC学习篇之---类的三大特性(封装,继承,多态) 6.OC学习篇之[email protected]关键

(转载)OC学习篇之---循环引用问题

在之前的一片文章中,我们介绍了数组操作对象的时候引用问题以及自动释放池的概念,今天我们继续来看一下引用计数中一个痛疼的问题:循环引用 关于循环引用的问题,这里就不做太多解释了,就是多个对象之间相互引用,形成环状. 来看一个具体的例子:Dog类和Person类之间相互引用 Dog.h 1 // 2 // Dog.h 3 // 29_CyclePointer 4 // 5 // Created by jiangwei on 14-10-13. 6 // Copyright (c) 2014年 jia

OC学习篇之---循环引用问题

在之前的一片文章中,我们介绍了数组操作对象的时候引用问题以及自动释放池的概念: http://blog.csdn.net/jiangwei0910410003/article/details/41926183 今天我们继续来看一下引用计数中一个痛疼的问题:循环引用 关于循环引用的问题,这里就不做太多解释了,就是多个对象之间相互引用,形成环状. 来看一个具体的例子: Dog类和Person类之间相互引用 Dog.h // // Dog.h // 29_CyclePointer // // Crea

黑马程序员-OC学习笔记之autorelease与自动释放池

---------------------- IOS开发.Android培训.期待与您交流! ---------------------- 一.autorelease autorelease与release相似,是OC中的一个对象方法.这两个方法都能把对象的引用计数器减1,但是release是一个精确的减1,对对象的操作只能在release之前进行,如果是在之后,就会出现野指针错误:而autorelease是一个不精确的引用计数器减1,当给对象发送autorelease消息时,对象就会被放到自动

OC中对象元素的引用计数 自动释放池的相关概念

OC中数组对象在是如何处理对象元素的引用计数问题的,同时介绍一下自动释放池的相关概念 一.数组对象是如何处理对象元素的引用计数问题[objc]  view plaincopy 1. //   2. //  main.m   3. //  26_NSArrayMemeryManager   4. //   5. //  Created by jiangwei on 14-10-12.   6. //  Copyright (c) 2014年 jiangwei. All rights reserve

OC基础(十三)autorelease自动释放池

autorelease 自动释放池 autorelease是一种支持引用计数的内存管理方式,只要给对象发送一条autorelease消息,会将对象放到一个自动释放池中,当自动释放池被销毁时,会对池子里面的所有对象做一次release操作 优点:不用再关心对象释放的时间,不用再关心什么时候调用release 原理:autorelease实际上只是把对release的调用延迟了,对于每一个autorelease,系统只是把该 Object放入了当前的autorelease pool中,当该pool被

OC基础笔记——自动释放池

autorelease:延长对象生命周期 把对象放到离自己最近那个自动释放池中 当自动释放池销毁的时候,它会把放在其中所有对象进行一次release的操作 它和对象在哪里创建没有关系 自动释放池的原理: 1.系统中存在一个自动释放池栈, 当遇到 @autoreleasepool { 把这个自动释放池压入栈中 2.但遇到与之对应 } 自动释放池,出栈,它出栈的时候,会对池中所有对象进行一次release操作 3.自动释放池栈中,只有栈顶自动释放池是活动的,其他的都在休眠 4.当你调用autorel