NSNotification是否保留对象?

MDM*_*nty 21 iphone nsnotifications nsnotification ios

我的问题是关于添加到-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];
Run Code Online (Sandbox Code Playgroud)

NSG*_*God 31

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

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

我想你可能正在设想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];
Run Code Online (Sandbox Code Playgroud)

  • 如果NSNotifications仅用于NSNotificationCenters,则会出现这种情况.NSNotificationQueue怎么样?在这种情况下,我们是异步发布的,无论是否保留对象都很重要. (5认同)

jus*_*tin 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;
}
Run Code Online (Sandbox Code Playgroud)