我有一个对象
id currentObject;
我想通过通知。问题是我不知道如何正确发布它,内存管理文档让我发疯。
我现在这样做:
[[NSNotificationCenter defaultCenter] postNotificationName:@"MessageReceived" object:nil userInfo:[NSDictionary dictionaryWithObjectsAndKeys:[currentObject copy], @"key", nil]];
[currentObject release];
应该是:
[[NSNotificationCenter defaultCenter] postNotificationName:@"MessageReceived" object:nil userInfo:[NSDictionary dictionaryWithObjectsAndKeys:[currentObject autorelease], @"key", nil]];
(适用于iPhone,iOS4.0)
提前致谢!
答案 0 :(得分:1)
无论哪种方式都可以。虽然这两种方法之间存在微小差异,但在这种情况下不应产生任何实际差异。只要你以某种方式释放自己的所有权,你就没事了。字典和通知中心将在自己的时间内处理自己的所有权问题。
编辑:哎呀,错过了什么。我刚才所说的仍然适用于你在copy
调用currentObject
的第一个例子中的但。这会创建一个 new 位的所有权 - 您会立即忘记,从而产生内存泄漏。
由于我们没有看到您创建currentObject
的位置,因此两个版本都可能过度释放。但假设你alloc
它,你就足够了。但是如果你坚持打电话给copy
- 可能是不必要的,虽然你已经了解更多关于currentObject
是什么以及后来会发生什么 - 你需要release
新副本也可以将copy
电话打包在autorelease
中,如下所示:
[[NSNotificationCenter defaultCenter] postNotificationName:@"MessageReceived" object:nil userInfo:[NSDictionary dictionaryWithObjectsAndKeys:[[currentObject copy] autorelease], @"key", nil]];
[currentObject release];
如果不清楚,请仔细阅读object ownership docs。
答案 1 :(得分:0)
除非文档另有说明,否则您可以假定传递对象的对象使用传入的对象来解决自己的所有权问题。例如,滚动到NSNotificationCenter docs概述的底部,并且有一个关于它不保留观察者这一事实的呼吁。
您的第一个示例泄漏是因为您将对象的副本传递给-copy制作的字典。因此,您拥有对象和副本,但您永远不会释放副本(字典也保留副本)。如果希望字典包含对象的副本而不是对象本身,请执行以下操作:
[[NSNotificationCenter defaultCenter]
postNotificationName:@"MessageReceived"
object:nil
userInfo:[NSDictionary dictionaryWithObjectsAndKeys:[[currentObject copy] autorelease], @"key", nil]];
第二个例子很好,只要你拥有currentObject,即你用new,alloc或包含副本的方法获得它,或者你以前保留过它。