3

我了解在使用 Alloc、new 或 copy 时,您拥有该对象并需要释放该对象。我明白,如果我保留一个对象,我需要释放它。

但是,如果我在方法的末尾有以下语句:

return [[UIImage alloc] initWithContentsOfFile:path];

我拥有该UIImage对象,因为我分配了内存空间,但我不再引用它,因为它已返回给调用者。在我的dealloc()方法中,我无法发布它,因为我没有参考。

所以我的问题是,这是否正确:

return [[[UIImage alloc] initWithContentsOfFile:path] autorelease];

我相信在这种情况下,调用者可以保留返回的对象,如果他们想获得所有权并最终需要释放自己。

谢谢你的帮助。

4

5 回答 5

5

你的假设是正确的。当你返回一个对象时,你应该将它作为一个自动释放对象传递。

当您需要发送延迟释放消息时使用自动释放 - 通常在从方法返回对象时......

于 2012-08-20T14:13:40.493 回答
4

自动释放的重点是围绕返回对象构建的。

- (id)bad {
    MyObj *obj = [[MyObj alloc] init];
    return obj;
}

此代码正确返回所有内容,但您(作为开发人员)必须确保稍后释放该对象。

- (id)moreBad {
    MyObj *obj = [[MyObj alloc] init];
    return [obj release];
}

此代码按预期使用内存,在一个范围内平衡保留和释放,但返回的对象现在是垃圾(预计会崩溃)。

- (id)good {
    MyObj *obj = [[MyObj alloc] init];
    return [obj autorelease];
}

此代码是“延迟发布”。即你可以retain在调用方的对象和对象是安全的。如果您没有NSAutoreleasePool范围,它肯定会被破坏,但这是一种非常罕见的情况,而且您大多知道何时发生(最常见的情况是在没有“默认”自动释放池的情况下启动一个新线程)。

因此,通常的做法是在一个范围内平衡保留(和类保留)和释放方法。下一个建议是始终使用 alloc-init-autoreleased 对象,如果您有内存问题(例如在循环中自动释放大量对象),则切换到不同的版本。下一个建议是切换到 ARC。

于 2012-08-20T14:19:49.937 回答
0

为什么要分配它?说啊:

return [UIImage imageWithContentsOfFile:path];

没有什么可分配的——没有什么可释放的。

此外,这是使用 ARC 时的最佳选择,其中释放尝试会导致错误。

于 2012-08-20T14:13:43.707 回答
0

两个答案都是正确的,但是你可能并不总是有一个方便的方法供你使用,所以我喜欢做的是你对自动释放所做的事情:

- (MySomethingClass*)giveMeAFancyObject{
    MySomethingClass *obj = [[[MySomethingClass alloc] init] autorelease];
    obj.name = @"Something";
    // do some setting up maybe
    return obj;
}
于 2012-08-20T14:19:59.047 回答
0

但是,如果您使用 release,则字符串将在返回之前被释放(并且该方法将返回无效对象)。使用自动释放,您表示您想要放弃所有权,但您允许方法的调用者在释放之前使用返回的字符串。

于 2012-08-20T14:34:02.760 回答