这是在iPhone上。
那么如果我有像
这样的功能呢?- (SomeObject*)buildObject;
我是否需要传入一个我已经在外部分配的变量,如
- (void)assignObject(SomeObject** out);
或者我可以吗
- (SomeObject*)buildObject
{
return [[[SomeObject alloc] init] autorelease];
}
并像
一样使用它SomeObject* obj = [[otherObject buildObject] retain];
我想做最后一个,但据我所知,这是未定义的,因为autorelease只保证对象直到函数结束?
答案 0 :(得分:6)
在Objective-C中,内存管理合同如下:调用alloc的人负责调用release。如果构造函数调用[[[class alloc] init] release],则会快速创建并销毁该对象。
要解决这个问题,构建函数需要使用自动释放,如下所示:
return [[[Class alloc] init] autorelease];
注册要在当前运行循环结束时释放的对象,除非保留它,例如构造函数的调用者。在您的情况下,第二个示例正是您想要做的。
所以:
- (SomeClass*) buildObject {
return [[[SomeClass alloc] init] autorelease];
}
- (void) doSomething {
c = [self buildObject];
// Call [c retain] if you want c to stay around after the current run
// loop is finished and clean it up later, e.g. in your delloc method.
}
答案 1 :(得分:4)
如何在Cocoa中解决这个问题;阅读文档了解详情。
基本上,如果您的方法以 init ,新或复制开头,则会返回一个保留的对象,您必须释放它。
如果您提供便利方法,则返回自动释放的对象。
这意味着:
- (id) initMyObject
{
self = [super init];
if (self) {
// do something
}
return self
}
➔您必须释放使用此方法获得的对象
- (MyObject *) myObject
{
return [[[MyObject alloc] initMyObject] autorelease];
}
➔这是一种方便的方法 - 该对象是由该方法自动释放的,你必须保留它如果你要保持它的时间长于自动释放池清空(你应该假设在当前方法结束)。
答案 2 :(得分:1)
Autorelease保证对象直到当前NSAutoreleasePool的释放/排出。
从方法中返回自动释放的对象是完全可以接受的(和标准做法)。
答案 3 :(得分:1)
你可以做你想做的事。在释放当前自动释放池之前,Autorelease不会向对象发出释放消息。发生这种情况要么是因为你明确地要求它(通过分配+启动NSAutoreleasePool然后将其耗尽),要么是因为系统这样做了。系统自动释放池的创建和排放发生在事件周期的开始和结束时;来自内存管理编程指南:
自动应用套件 在一个开头创建一个池 事件循环(或事件循环迭代), 例如鼠标按下事件,和 最后发布它,所以你的代码 通常不必担心 它们。
在实践中,这意味着您想要做的事情是安全的,因为您编写的所有代码将在一个事件周期内一起执行。
答案 4 :(得分:0)
使用最后一个是安全的。我在每个应用程序中都使用这种风格,从未遇到过问题。自动释放将持续许多很多很多执行周期,比函数结束时间长得多。