NSNotificationCenter 观察者没有收到通知

Posted

技术标签:

【中文标题】NSNotificationCenter 观察者没有收到通知【英文标题】:NSNotificationCenter Observer Not Receiving Notification 【发布时间】:2012-11-15 13:38:52 【问题描述】:

我知道未收到通知的标准原因:

释放或取消注册的对象。 作为观察者移除对象。 未注册为观察者。 注册错误通知或发布错误通知。

我可以很高兴地说,我非常确定这些都不会发生。我想最有可能的是该对象在某个时候被无效并重新创建,但它在初始化时注册了通知。

这里是我注册的地方:

/**
 *  initialises an object with a unique file url
 *
 *  @param  url                         the url to set as the file url
 */
- (id)initWithFileURL:(NSURL *)url

    if (self = [super initWithFileURL:url])
    
        self.entries                    = [[NSMutableArray alloc] init];

        //  we want to be notified when a note has changed
        [[NSNotificationCenter defaultCenter] addObserver:self
                                                 selector:@selector(noteChanged)
                                                     name:@"com.andbeyond.jamesvalaitis.notesChanged"
                                                   object:self];

        NSLog(@"Just registered for 'com.andbeyond.jamesvalaitis.notesChanged'");
    

    return self;

这里是我发布通知的地方:

/**
 *  save the note content
 */
- (void)saveNote

    if (_isChanged)
    
        //  save to the text view to the note's contents
        self.note.noteContent           = self.noteView.text;

        //  post a notification that we changed the notes
        [[NSNotificationCenter defaultCenter] postNotificationName:@"com.andbeyond.jamesvalaitis.notesChanged" object:nil];

        NSLog(@"Just posted 'com.andbeyond.jamesvalaitis.notesChanged'");

        //  make sure we know it's already saved
        _isChanged                          = NO;
    

这是未被调用的方法:

/**
 *  called when a note has changed
 */
- (void)noteChanged:(NSNotification *)notification

    NSLog(@"Just received for 'com.andbeyond.jamesvalaitis.notesChanged'");

    //  save the notes
    [self saveToURL:self.fileURL forSaveOperation:UIDocumentSaveForOverwriting completionHandler:^(BOOL success)
    
        if (success)
            NSLog(@"Note updated.");
    ];

这是控制台,说明我注册并发布通知:

2012-11-15 13:27:50.958 iCloud Custom[11269:907] 刚刚注册 'com.andbeyond.jamesvalaitis.notesChanged'

2012-11-15 13:28:24.184 iCloud 自定义[11269:907] 刚刚发布 'com.andbeyond.jamesvalaitis.notesChanged'

The whole project can be found here.

【问题讨论】:

在帖子中添加 noteChanged 方法... 你的选择器还是这样的@selector(noteChanged) .. 那它怎么称呼它 - (void)noteChanged:(NSNotification *)notification ???你需要像这样改变你的选择器@selector(noteChanged:) @DineshRaja:嗨,Dinesh 和 James,我面临着类似的问题,并且已经阅读了这篇文章的所有答案,并应用了这些建议;事情还没有为我解决。我能够成功发布通知并声明观察者。但是进行检查的逻辑不会被执行。我应该如何分享代码?还是我应该发布一个相当重复的问题? @ArchitKapoor 您可以使用您的代码发布一个新问题或将代码放在 gist/pastebin 上并在此处共享链接。届时我们可以为您提供帮助。 【参考方案1】:

我想我已经找到了答案。您正在名为 NotesDocument.mUIDocument 文件中创建通知。所以当你创建一个观察者时,你将对象设置为self。这意味着 NotesDocument 对象。但是当您post the notification 时,您将对象作为nil 发送。所以it wont observe the notification 根据文档。 解决这个问题的简单方法是在创建通知时需要将对象设置为nil。否则你需要传递一个NotesDocument Object

查看下图和参数详情,了解 addObserver 通知方法。

查看notificationSender 参数。观察者想要接收其通知的对象;也就是说,只有此发送者发送的通知才会传递给观察者。

【讨论】:

我真是个白痴。当我注册通知时,我完全不是想将对象设置为 self 。这现在完美无缺。非常感谢你。 我刚刚遇到了完全相同的问题,不敢相信我这么快就找到了答案。这是一件小事;很容易被忽视,很难被发现。非常感谢。 花了大约 20 分钟的时间认为我有 nil 作为观察者的对象,它是 self。感谢您的这篇文章促使我检查我期望的粉红色属性是正确的。 :) 在 Swift 3 中有同样的事情,尽管我的案例是在添加观察者时错误地定义了通知名称。你的回答有帮助 =)【参考方案2】:

更改以下内容:

...
selector:@selector(noteChanged:) 

...
- (void) noteChanged:(NSNotification *) notification
...

【讨论】:

刚刚做了这个更改,但它不起作用。还是谢谢你。 尝试在两个地方都使用静态字符串,而不是使用不同的字符串进行通知。它们看起来完全一样,但可能有些奇怪。【参考方案3】:

以下网址将解决您的问题。

http://mobile.tutsplus.com/tutorials/iphone/ios-sdk_nsnotificationcenter

【讨论】:

我用过很多 NSNotificationCenter 并且知道实现它的过程。你坚持认为你的链接会对我有所帮助是相当可敬的,但遗憾的是错误的。

以上是关于NSNotificationCenter 观察者没有收到通知的主要内容,如果未能解决你的问题,请参考以下文章

iOS NSNotificationCenter 移除通知带来的crash

IOS学习之NSNotificationCenter消息机制

Swift:通过 NSNotificationCenter 的键盘观察器不起作用

NSNotificationCenter带参

NSNotificationCenter removeObserver:在 dealloc 和线程安全中

什么是 NSNotification?