Objective-C基础教程五(内存管理)

内存管理是程序设计中最常见的资源管理的一部分


1,对象的生命周期:

对象的生命周期包括诞生(通过alloc或new方法实现),生存(接收消息和执行操作),交友(借助方法的组合和参数)以及当他们的声明结束时最终死去(被释放)。当对象的生命周期结束时,他们的原材料(内存)将被回收以供新的对象使用。


1.1引用计数

Cocoa采用了一种称为引用计数(reference counting)的计数,有时也叫做保留计数。

当使用alloc,new方法或者通过copy消息(生成接收对的一个副本)创建一个对象时,对象的保留计数器值被设置为1。当要增加对象的保留计数器值,可以给对象发送一条retain消息。要减少对象的保留计数器值,可以给对象发送一条release消息

当一个对象因其保留计数器归0而即将被销毁时,Objective-C自动向对象发送一条dealloc消息。你可以在自己的对象中重写dealloc方法。可以通过这种方法释放已经分配的全部相关资源。

获取保留计数器的当前值,可以发送retainCount消息。


1.2对象所有权

如果一个对象具有指向其他对象的实例变量,则称该对象拥有这些对象。例如,在CarParts类中,car对象拥有其指向engine和tire对象。通用,如果一个函数创建了一个对象,则称该函数拥有它创建的这个对象。在CarParts类中,main()函数创建了一个新的car对象,因此成main()函数拥有car对象。


1.3访问方法中的保留和释放

- (void) setEngine: (Engine *) newEngine
{
	[newEngine retain];
	[engine release];
	engine = newEngine;
}

首先保留新的对象,然后释放旧的对象。



2,自动释放

2.1所有对象全部入池

Cocoa中有一个自动释放池(autorelease pool)的概念。NSAutoreleasePool类。顾名思义,它是一个存放实体的池(集合),这些实体可能是对象,能够被自动释放

NSObject类提供了一个autorelease方法:

- (id) autorelease;

该方法预设定了一条在将来某个时间发送的release消息,其返回值是接收消息的对象。当给一个对象发送autorelease消息时,实际上是将该对象添加到NSAutoreleasePool中。当自动释放池被销毁时,会向该池中所有对象发送release消息


现在可以编写一个能够很好地管理内存的description方法:

- (NSString *) description
{
	NSString * description;
	description = [[NSString alloc] initWithFormat: @"I am %d years old", 4];
	return([description autorelease]);
}
用下面的代码调用
NSLog(@"%@", [someObject descripion]);
因为description方法首先创建了一个新的字符串对象,然后自动释放该对象,最后将其返回给NSLog()函数,所以内存管理问题至此的道路圆满解决。由于description方法汇总的字符串对象时自动释放的,该对象暂时被放入当前活动的自动释放池中,等到调用NSLog()函数的代码运行结束后,自动释放池被自动销毁。


2.2自动释放池销毁的时间

在我们一直使用的Foundation库工具中,创建和销毁自动释放池的方法非常明确:

NSAutoreleasePool *pool;

pool = [[NSAutoreleasePool alloc] init];

....

[pool release];


当使用AppKit时,Cocoa定期自动为你创建和销毁自动释放池。通常是在程序处理完当前事件(如鼠标单击或按键)以后执行这些操作。


3,Cocoa内存管理规则

如果我使用了new,clloc或copy方法获得了一个队,则我必须释放或自动释放该对象。

无论什么时候拥有一个对象,有两件事必须弄清楚:怎样获得该对象的?打算拥有该对象多长时间?

内存管理规则

获得途径临时对象拥有对象
alloc/new/copy不再使用时释放对象在dealloc方法中释放对象
任何其他方法不需要执行任何操作获得对象时保留,在dealloc方法中释放对象

3.1临时对象

临时对象的意思和java中是类似的,在方法中的临时定义成的变量,举下面两个例子,

NSMutableArray *array;

array = [[NSMutableArray alloc] init];//count:1

//use the array

[array release];//count:0;需要使用release消息

如果使用任何其他方法获得一个对象,例如arrayWithCapacity这样的工厂方法,则不需要关系如何销毁该对象。

NSMutableArray *array;

array = [NSMutableArray arrayWithCapacity: 17];//count: 1. autorelease;

//use the array


3.2拥有对象

通常,你可能希望在多个代码行一直拥有某个对。常见的方法是:在其他对象的实例变量中使用这些对象,将它们加入诸如NSArray或NSDictionary集合中,或者将其作为全局变量使用。

如果使用new alloc或copy方法获得一个对象,则不需要执行任何其他操作,该对象的保留计数器值为1,因此它一直被保留,只是一定要在拥有该对象的dealloc方法中释放该对象。

- (void) doStuff{
	//flonArray is an instance variable
	flonArray = [NSMutableArray new];
}//doStuff

- (void) dealloc{
	[flonArray release];
	[super dealloc];
}//dealloc

 使用其他的方法产生对象需要将计数器增加.

- (void) doStuff{
		//flonArray is an instance variable
		flonArray = [NSMutableArray arrayWithCapacity: 17];//count 1 ,autoreleased
		[flonArray retain];//count 2,1 autorelease
	}//doStuff

	- (void) dealloc{
		[flonArray release];//count 0
		[super dealloc];
	}//dealloc


清理自动释放池

NSAutoreleasePool *pool;
	pool = [[NSAutoreleasePool alloc] init];
	int i;
	for(i=0;i<10000; i++){
		id object = [someObject objectAtIndex: i];
		NSString *desc = [object description];
		//and do somethine with the description
		if(i %1000 == 0){
			[pool release];
			pool = [[NSAutoreleasePool alloc] init]
		}
}

自动释放池以栈的形式实现,当你创建一个新的自动释放池时,它将被添加到栈顶。接收autorelease消息的对象将被放入最顶端的自动释放池中。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值