您的位置:首页 > 移动开发 > Objective-C

黑马程序员--Objective-C之--自动释放池的概念以及使用

2015-03-30 00:04 393 查看

------IOS培训期待与您交流! -------

今天我们来看一下OC中数组对象在是如何处理对象元素的引用计数问题的,同时介绍一下自动释放池的相关概念

一、数组对象是如何处理对象元素的引用计数问题

//
//  main.m
//  26_NSArrayMemeryManager
//
//  Created by waterfoxjie on 15-03-29.
//  Copyright (c) 2015年 waterfoxjie. All rights reserved.
//

#import <Foundation/Foundation.h>

#import "Dog.h"

int main(int argc, const charchar * argv[]) {

Dog *dog1 = [[Dog alloc] init];
Dog *dog2 = [[Dog alloc] init];

NSMutableArray *array = [[NSMutableArray alloc] init];

//数组会对每一个元素retain
[array addObject:dog1]; //dog1计数=2
[array addObject:dog2]; //dog2计数=2

[dog1 release];
[dog2 release];

//当数组销毁的时候,会将所有的元素release
[array release];//数组销毁

//当数组移除所有的元素的时候,会讲所有的元素release
[array removeAllObjects];

return 0;
}


我们定义了Dog类,然后定义了NSMutableArray数组存放两个Dog对象,OC中在将对象放到数组中的时候,会自动调用retain方法,当数组对象本身被销毁的时候,会调用

所有元素的release方法,当移除数组中所有的元素的时候,会调用元素的release方法

二、自动释放池的概念

//
//  main.m
//  27_AutoReleasePool
//
//  Created by waterfoxjie on 15-03-29.
//  Copyright (c) 2015年 waterfoxjie. All rights reserved.
//

#import <Foundation/Foundation.h>

#import "Dog.h"

int main(int argc, const charchar * argv[]) {

/*
//创建一个自动释放池
//有作用域的问题,在{}中定义的东西外部是不能访问的,这点和NSAutoreleasePool有区别的

@autoreleasepool {//等价于[[NSAutoreleasePool alloc] init]

Dog *dog2 = [[Dog alloc] init];
[dog2 retain];

}//等价于[pool release]

//创建一个自动释放池
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

Dog *dog1 = [[Dog alloc] init];//计数:1

//将dog1对象加入到自动释放池中,却别于之前的release方法
//加入到自动释放池中之后,不是代表我们不需要管理引用了,只是自动释放池自动会调用一次release
//当自动释放池销毁的时候,释放池会对池中每一个对象调用一次release

[dog1 autorelease];

NSLog(@"dog1计数:%ld",dog1.retainCount);

//销毁自动释放池
//这时候会调用dog1的release方法,dog1对象就被销毁了
[pool release];
*/

//自动释放池的嵌套
NSAutoreleasePool *pool1 = [[NSAutoreleasePool alloc] init];

//添加我们的代码
//dog1放到了pool1中
Dog *dog1 = [[Dog alloc] init];
[dog1 autorelease];

//自动释放池的嵌套
NSAutoreleasePool *pool2 = [[NSAutoreleasePool alloc] init];

//dog2放到了pool2中
Dog *dog2 = [[Dog alloc] init];
[dog2 autorelease];

//pool2销毁了
[pool2 autorelease];

//pool1销毁了
[pool1 release];

//下面的代码就是有问题的
//[person setDog:[[Dog alloc] init];
//正确的写法
//Dog *dogs = [[[Dog alloc] init] autorelease];

return 0;
}


我们在之前的文章中,定义一个对象的时候都会产生一个自动释放池,然后在释放池中编写我们的代码,自动释放池是系统提供的一种帮助我们去管理对象的引用计数问题。

但是有时候代码必须在{...}中编写,这样的话就会产生作用域的问题,就是在{...}中定义的变量,在{...}外面不能使用。

所以OC中就有 了另外的一种方式:NSAutoreleasePool这个类

这种自动释放池可以实现嵌套

NSAutoreleasePool *pool1 = [[NSAutoreleasePool alloc] init];

//write code...

//pool1销毁了

[pool1 release];


上面的代码就相当于建立了一个自动释放池pool1,但是在这个中间的代码,如果要加入到这个池中,必须调用autorelease方法:

//dog1放到了pool1中

Dog *dog1 = [[Dog alloc] init];

[dog1 autorelease];


而且,这样定义一个池子还可以嵌套使用,直接看上面的例子代码,这样这个自动释放池我们就可以控制了。比系统提供的自动释放池可操作的地方很多

下面就直接对比一下:

NSAutoreleasePool *pool1 = [[NSAutoreleasePool alloc] init];

//这行代码就相当于系统自动释放池的
{

[pool1 release];

//这行代码就相当于系统自动释放池的
}


这样就好理解了吧
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐