我需要在将对象作为用户数据发送到NotificationCenter之前自动释放它吗?

4
我需要使用postNotificationName:object:userInfo:方法发布通知,我将一个自定义类FileItem作为userInfo传递,以便在另一端获取它。我应该像这样使用autorelease吗?
FileItem *item = [[[FileItem alloc] init] autorelease];
[[NSNotificationCenter defaultCenter] postNotificationName:@"dataReceived" object:self userInfo:item];
[item release];

还是我可以只使用alloc,然后在将对象传递给默认通知中心后立即release它吗?
FileItem *item = [[FileItem alloc] init];
[[NSNotificationCenter defaultCenter] postNotificationName:@"dataReceived" object:self userInfo:item];
[item release];

我正在努力养成一种惯例,即我假设每当我将一个对象作为参数传递给另一个对象的消息时,接收对象会在需要时进行保留,因此我可以安全地释放该参数?
2个回答

3
第二个选项是正确的。你也可以只执行以下操作:
FileItem *item = [[[FileItem alloc] init] autorelease];
[[NSNotificationCenter defaultCenter] postNotificationName:@"dataReceived" object:self userInfo:item];

传统的经验法则是,在每个alloccopyretain操作之后,需要相应的release(或autorelease)操作,进行过度释放可能会导致您的对象被过度释放。

谢谢。现在我明白多了。但是,当我在.h文件中声明一个NSString *,在dealloc方法中释放NSString *,但在init文件中没有alloc / copy / retain时,我经常会感到困惑,只有类似于stringObject = [NSString stringWithFormat@"....."]的东西。你能告诉我这种情况下发生了什么吗? - Ben
1
在这种情况下,您不应该在dealloc方法中释放字符串:没有alloc / copy / retain,也没有release。但是,您可能想要做的是像这样:stringObject = [[NSString stringWithFormat:@"…"] retain]; 然后在dealloc方法中释放stringObject。这确保了字符串不会消失,直到您准备好使用它。 - Matt Ball
正确,没有分配/复制/保留,没有所有权,没有释放。谢谢。 - Ben
我会将mutableCopy添加到需要最终释放的调用列表中。 - Abizern

2
autorelease的意思是“稍后发送release”。发送autoreleaserelease到同一对象会释放两次。正如Matt Ball所说,您的后一个示例和他的示例是等效的。
更重要的是,您只释放自己拥有的东西。一旦您释放它,您就不再拥有它,并且应该认为它不再是您的。在您的第一个示例中,在第一次释放后,您已经停止拥有该对象。那么第二次释放显然是错误的,因为它释放了一个您不拥有的对象。
除非您也拥有它,否则永远不要释放其他对象拥有的对象。

我能理解将已经发送到自动释放池的对象释放掉可能会有问题。感谢您的解释。我想知道是否应该假设每次向另一个对象发送消息时,都应该假定该方法将保留它。一旦我传递了对象,我可以在下一行释放它吗? - Ben
你不应该关心其他对象是否会保留它。问题是:你拥有它吗?如果是,你就保留或复制它。如果不是,你就不保留。然后,稍后释放你所拥有的东西。就这么简单。而局部变量中的对象通常是你不拥有的东西;你将自己拥有的东西放入实例变量中,或者放入实例变量中的集合对象中。 - Peter Hosey

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接