我总是在我的书中说,第二种方式更好。但在过去,有些人不同意,尤其是。在 iOS 上。有什么不同?
- 有什么区别吗?
两种变体都分配一个对象。两种变体都负责发布它。(“自动释放是一种释放。”)但他们在不同的时间点这样做:
- Variant:对象在 ARP 结束时释放,至少在 runloop 结束时。
- 变体 2:对象立即被释放
release
。
(两者:如果没有额外的参考。)
- 为什么我需要-autorelease?
在某些情况下,release
如果不违反 MM 规则,a 是不可能的。最简单的情况是您想要返回一个分配的对象。谁应该释放它?创建方法?这将返回一些可能被释放的东西。发送消息的方法?这会使 +1 方法alloc
与 -1 方法(如release
. 没有出路。
例子:
- (NSString*)fullName
{
NSString *fullName = [[NSString alloc] initWithFormat:@"%@, %@", self.lastName, self.firstName];
return fullName; // Who balance +alloc?
}
通过自动释放对象,您的方法保持平衡并可以安全地返回对象。
在其他情况下,这是摆脱依赖关系的便捷方式。想象一下这段代码:
Person *person = …;
NSString *name = person.name;
[person release], person=nil; // Imagine that this will dealloc the instance.
// name is invalid, because person released it.
有了autorelease
你就没有这个问题了。有几种解决方案:
getter 将retain
,发送autorelease
到返回值。ARP 中还有一个额外的引用来防止字符串被解除分配:
- (NSString*)name
{ return [[_name retain] autorelease]; }
或者使用该方法的人这样做:
NSString *name = [[person.name retain] autorelease];
问题的下一个问题release
是,它更难使用return
,break
或者continue
:
while (…)
{
id object = [[Class alloc] …]
if (…)
{
break;
}
[object release];
}
自动释放没有问题。
Next: 出于某些原因,使用便利分配器(如果存在)是个好主意。从那里返回的对象不允许显式释放,因此放弃引用的代码依赖于如何设置引用。为什么不一直使用自动释放?
- 自动释放的缺点是什么
对象删除可能会延迟,因此您可能会遇到内存占用问题。但我个人认为,@autorelease{}
这比release
.