1.对象的生命周期包括诞生(通过alloc或new方法实现)、生存(接收消息和执行操作)、交友(借助方法的组合和参数)以 及当它们的生命结束时最终死去(被释放),当对象的生命周期结束时,它们的原材料(内存)将被回收以供新的对象使用。
2.引用计数:
当使用alloc、new方法或者通过copy消息(生成接收对象的一个副本)创建一个对象时,对象的保留计数器值被设置为1;
要增加对象的保留计数器值,可以给对象发送一条retain消息,
要减少对象的保留计数器值,可以发一条release消息。
当一个对象的保留计数器归0时自动向对象发送一条dealloc消息。dealloc是自动调用的,切记手动调用,此方法可以重写。
//返回一个id类型的值,可以增加保留计数器的同时并要求对象完成某种操作, - (id) retain
例如
[[car retain]setTire:tire atIndex:2] - (void) release; -(unsigned) retainCount;
3.对象所有权
如果一个对象具有指向其他对象的实例变量,称该对象拥有这些对象,并意味着要负责确保对其拥有的对象进行清理。
Car类中engine setter方法
-(void) setEngine: (Engine *) newEngine;
main函数中调用该方法
Engine *engine = [Engine new];
[Car setEngine: engine];
main函数和car类同时拥有engine对象,car类正在使用engine对象,所以不能是main函数释放对象
main函数随后可能用到engine对象,所以也不可能是car类。
解决办法是让car类保留engine对象,将engine对象的保留计数器增加到2,
car类应该在setEngine方法中保留engine对象,而main函数运行结束时释放engine对象,当car类完成其任务时再释放engine对象(在其dealloc方法中),最后engine对象占用的资源被回收。
4.访问方法中的保留和释放
- (void) setEngine: (Enigne *) newEngine{
[newEngine retain];
[engine release];
engine = newEngine;
}//setEngine
如果首先保留新的newEngine,而newEngine与engine是同一个对象,保留计数器值将先增加然后立即减少,
但是不会归0,engine对象意外的未被销毁,从而导致错误。
在访问方法中如果先保留对象,然后再释放旧对象,则不会出问题。
5.自动释放
NSObject类提供了一个autoRelease方法:
- (id) autoRelease;
该方法预先设定了一条在将来某个时间发送的release消息,其返回值是接收消息的对象。当给一个对象发送autoRelease消息时实际上是该将该对象
添加到NSAutoreleasePool中,当自动释放池被销毁时会向该池中的所有对象发送release消息。
可按如下格式编写方法
- (NSString *)description{
NSString *desc;
desc = [[NSString alloc] initWithFormat: @"I am %d years old",4];
return [desc autoRelease];
}
可以如下调用
NSLog(@"%@",[somoObject description]);
6.自动释放池工作过程
int main(int argc, const char *argv[]){
NSAutoreleasePool *pool;
pool = [[NSAutoreleasePool alloc] init];
RetainTracker *tracker;
tracker = [RetainTracker new];//count 1
[tracker retain];//count 2
[tracker autorelease];//count still 2
[tracker release];//count 1
NSLog(@"releaseing pool");
[pool release];
return (0);
}//main
7.内存管理规则
如果使用new,alloc或copy操作获得一个对象,则该对象的保留计数器值加1,release减1
如果通过任何其他方法获得一个对象,则假设该对象的保留计数器值为1,而且已经被设置为自动释放
如果保留了某个对象,则必须保持retain方法和release方法使用的次数相同
8.拥有对象
如果在多个代码行中一直拥有某个对象,常见的方法是在其他对象的实例变量中使用这些对象,将他们加入到诸如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
9.清理自动释放池
int i;
for(i=0; i<10000; i++){
id object = [someObject objectAtIndex: i];
NSString *desc = [object description];
//and do somethine with the description
}
在上面程序中会产生很多个闲置的字符串,直到自动释放池被销毁才能最终得到释放,解决这类问题的方法是在循环中创建自己的自动释放池。
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]
}
}
自动释放池以栈的形式实现:当你创建一个新的自动释放池时,它将被添加到栈顶。接收autoreales消息的对象将被放入最顶端的自动释放池中。
10.注意:如果开发Iphone软件,则不能使用垃圾回收,实际上,在编写iphone程序时,苹果公司建议不要在代码中使用autorelease方法,同时还要避免使用创建自动释放对象的便利函数.
本文详细介绍了对象的生命周期,包括诞生、生存、交友和死亡四个阶段,并深入探讨了引用计数、对象所有权、自动释放等内存管理核心概念,以及如何在代码中正确地使用这些机制。
1216

被折叠的 条评论
为什么被折叠?



