NSNotification postNotificationName in AppDelegate

2019-02-15 14:56发布

I can't get the selector method, receiveChatText, in the NSNotificationCenter to execute and I am wondering if the problem is because the NSNotification postNotificationName is in AppDelegate.m but NSNotificationCenter is in ViewController.m? I.E. can the postNotificationName know that the NSNotificationCenter is in another viewController file or is that something I need to tell it?

In a viewController.m I have

 -(id)init
 {
self = [super init];
if(self){
    [[NSNotificationCenter defaultCenter] addObserver:self  
                                      selector:@selector(receiveChatText:) 
                                                      name:ChatMessageReceived  
                                               object:nil];
 return self;
}

- (void)receiveChatText:(NSNotification *)note {
NSLog(@"received chat text");

}

and in the top level AppDelegate.m file I have the following:

 -(void) didReceiveMessage {
    [[NSNotificationCenter defaultCenter] postNotificationName:ChatMessageReceived 
                                          object:nil
                                          userInfo:nil];        
 }

Any ideas what could stop receiveChatText from being executed when didReceiveMessage is called?

3条回答
神经病院院长
2楼-- · 2019-02-15 15:22

I can't get the selector method, receiveChatText, …

First, it's receiveChatText:, with the colon. This is important in Objective-C —receiveChatText: and receiveChatText do not refer to the same method.

Second, “selector” does not mean what you think it means. A selector is the name of a method. You pass in the selector for the message you want the notification center to send to the observer. That is, you are telling the notification center “when this notification arrives, send a receiveChatText: message to me [the view controller]”.

… in the NSNotificationCenter …

The notification center doesn't have a receiveChatText: method. Your observer (self) does, which is why that's what you want the notification center to send the message to.

… to execute and I am wondering if the problem is because the NSNotification postNotificationName is in AppDelegate.m …

No such thing is in AppDelegate.m.

The app delegate posts a notification.

… but NSNotificationCenter is in ViewController.m?

No such thing is in ViewController.m.

The view controller observes for a notification.

As long as the view controller adds itself as an observer before the app delegate posts the notification, this will work. If it doesn't work, either one or both steps did not happen or they happened in the wrong order.

I.E. can the postNotificationName know that the NSNotificationCenter is in another viewController file or is that something I need to tell it?

The notification center isn't in either file. [NSNotificationCenter defaultCenter] is a singleton object, shared throughout your entire application amongst any objects that want to use it. That's how you're able to use it to have the app delegate communicate to the view controller and any other objects that are observing for the notification.

You are sending the default notification center a postNotificationName:object:userInfo: message. This is the same default notification center that you should have previously sent an addObserver:selector:name:object: message. As long as you start observing first, then send the notification to the same notification center, the notification center will be able to dispatch the notification to the observer(s) you added.

Any ideas what could stop receiveChatText

receiveChatText:

from being executed when didReceiveMessage is called?

  1. didReceiveMessage did not post a notification. Assuming the code you showed in your question is accurate, this is not the case.
  2. The view controller is not observing for the notification. Since it starts observing on creation, perhaps it hasn't been created yet. Or, it may be because you've overridden init rather than NS/UIViewController's initWithNibName:bundle:. Be aware of what different classes' designated initializers are; the documentation will usually say.
  3. The view controller is not observing for the notification yet: You posted the notification before the view controller started observing for it (i.e., before you created the view controller).

You might also want to pass the chat text as the object of the notification, or in its userInfo, rather than forcing all observers of the notification to retrieve it from an unspecified source.

查看更多
Summer. ? 凉城
3楼-- · 2019-02-15 15:35

That looks like it should work, as long as the value of ChatMessageReceived is the same in both instances.

Have you used the debugger to verify that the init method in the view controller file is called before the notification is posted in didReceiveMessage?

查看更多
爱情/是我丢掉的垃圾
4楼-- · 2019-02-15 15:40

+defaultCenter is a class method on NSNotificationCenter which will return the same NSNotificationCenter instance every time it is called in a given process regardless of where you call it from.

How is 'ChatMessageReceived' defined? It should be a NSString but is the name 'ChatMessageReceived' a valid symbol in the context of both of your classes?

查看更多
登录 后发表回答