NSNotification是否保留对象?

时间:2011-03-17 21:50:12

标签: iphone ios nsnotifications nsnotification

我的问题是关于添加到-postNotificationName:object: userInfo:方法的对象。

NSNotification是否保留对象? (与NSMutableDictionary或Array类似)...意味着我可以在发布通知后释放该对象

下面是一个代码片段,用于帮助描述我的问题......释放对象是否有效。 Apple文档的链接可能非常有用。

NSMutableDictionary *teamDictCopy = [self.teamDict mutableCopy];
[teamDictCopy setObject:[NSNumber numberWithInt:self.scrollViewIndex] forKey:@"imageIndex"];

if([self.statusButton.title isEqualToString:@"Completed"]){
    [[NSNotificationCenter defaultCenter] postNotificationName:@"UnComplete" object:teamDictCopy userInfo:nil];
}

[teamDictCopy release];

2 个答案:

答案 0 :(得分:31)

  

“NSNotification是否保留了   对象? (以类似的方式   NSMutableDictionary或Array)...   意思是我可以释放后的对象   发布通知“

我不确定该方法是否保留objectuserInfo参数,但在实践中,它并不重要。

我认为您可能会想到NSNotificationCenter正在创建这些通知并以异步方式广播它们,但事实并非如此。正如NSNotificationCenter的文档中所述(请参阅NSNotificationCenter Class Reference),同步发布通知:

  

通知中心提供   向观察员发出通知   同步。换句话说,   postNotification:方法没有   回到所有观察者都有   收到并处理了   通知。发送通知   异步使用   NSNotificationQueue。在一个   多线程应用程序,   通知总是在   通知的线程   被张贴,可能不一样   观察者注册的线程   本身。

因此,在您的代码中,通知中心会创建通知,然后通过默认中心进行广播。已注册通知名称和对象组合的任何对象都将收到通知,然后执行他们在注册该通知时指定的选择器。之后,控件返回发布通知的类。

换句话说,当您的代码到达[teamDictCopy release]行时,teamDictCopy已经被所有感兴趣的各方“使用”了。因此,释放它不应该有任何危险。

只是关于惯例的说明。通常,object:参数是发布通知的对象,userInfo:参数用于NSDictionary额外信息。因此,通常情况下,您将处理如下通知:

NSMutableDictionary *teamDictCopy = [self.teamDict mutableCopy];
[teamDictCopy setObject:
   [NSNumber numberWithInt:self.scrollViewIndex] forKey:@"imageIndex"];

if([self.statusButton.title isEqualToString:@"Completed"]){
 [[NSNotificationCenter defaultCenter] postNotificationName:@"UnComplete" 
     object:self userInfo:teamDictCopy];
    }

[teamDictCopy release];

答案 1 :(得分:5)

是 - 您可以在将对象设置为通知对象后释放该对象。

你也可以继承。

就具体文件/声明而言:具体而言,我不记得一个。

然而,当类型被识别为对象时,这是对象,它们的实例变量以及分布式通信和信令的基础。

我为你写了一个测试,所以你可以放心。如果没有保留对象,通知的用例很少。只需在指示处添加断点,然后在启用断点的情况下运行。享受!

#import <Foundation/Foundation.h>

@interface MONObject : NSObject
@end

@implementation MONObject

- (id)retain {
    return self; /* << add breakpoint here */
}

/* needed to counter retain override
   (although all MONObjects will leak in this example)
*/
- (void)release {
}

@end

int main(int argc, const char* argv[]) {
    NSAutoreleasePool * pool = [NSAutoreleasePool new];

    NSString * name = @"UnComplete";
    MONObject * obj = [MONObject new];
    [[NSNotificationCenter defaultCenter] postNotificationName:name object:obj userInfo:nil];
    [obj release], obj = 0;

    [pool drain];
    return 0;
}