通知时释放

时间:2010-07-08 14:13:42

标签: objective-c memory-management autorelease nsnotification

我有一个对象

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)

提前致谢!

2 个答案:

答案 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或包含副本的方法获得它,或者你以前保留过它。