21

我的问题是关于添加到-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];
4

2 回答 2

31

“NSNotification 是否保留对象?(以类似于 NSMutableDictionary 或数组的方式)......这意味着我可以在发布通知后释放对象”

我不确定该方法是否保留了objectanduserInfo参数,但实际上,这并不重要。

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

通知中心同步向观察者发送通知。换句话说,在 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];
于 2011-03-18T02:49:11.023 回答
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;
}
于 2011-03-17T21:55:56.133 回答