Search code examples
iphonensnotifications

NSNotification not calling the selector


I am creating a NSNotification in appDelegate.

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(checkRegister:) name:@"checkRegister" object:nil];

    return YES;
}

-(void)checkRegister:(NSNotification *) notification{

//Some code

} 

And I am posting notification in some other class:

-(void)connectionDidFinishLoading:(NSURLConnection *)connection
{
    NSLog(@"DONE. Received Bytes: %d", [webData length]);
    NSString *theXML = [[NSString alloc] initWithBytes: [webData mutableBytes] length:[webData length] encoding:NSUTF8StringEncoding];
    NSLog(@"%@",theXML);
    [theXML release];

    NSXMLParser *xmlParser = [[NSXMLParser alloc] initWithData: webData];
    [xmlParser setDelegate:self];
    [xmlParser setShouldResolveExternalEntities: YES];
    [xmlParser parse];
    [xmlParser release];

    [connection release];
    [webData release];

    if(strUserName != NULL)
        [[NSNotificationCenter defaultCenter] postNotificationName:@"checkRegister" object:nil];


}

The problem is that checkRegister is never called.


Solution

  • What is the purpose of your @"checkRegister" notification, you have if(strUserName != NULL) check in your if before you post the notification, but I don't see where do you setup that strUserName so definitely, try NSLog(@"%@", strUserName). I'm pretty sure it's null. if that strUserName is from the XML data your parse, you should post the notification after XML parsing code, which will be in your NSXMLParser delegate methods you implement. Which will be one of these you use.

    [xmlParser parse] doesn't block, so your

    if(strUserName != NULL)
        [[NSNotificationCenter defaultCenter] postNotificationName:@"checkRegister" object:nil];
    

    will be called, before xmlParser finished parsing, so, your strUserName is not set yet, and that's the reason it is nil and your postNoticationName: will not be called

    EDIT:

    put your

    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(checkRegister:) name:@"checkRegister" object:nil];
    

    on the very top of your application:didFinishLaunchingWithOptions: , it is very likely you post the notification in your main view before you registered for notification, for example

    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
    {
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(checkRegister:) name:@"checkRegister" object:nil];
        self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
        // Override point for customization after application launch.
        if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
            self.mainViewController = [[[MainViewController alloc] initWithNibName:@"MainViewController_iPhone" bundle:nil] autorelease];
        } else {
            self.mainViewController = [[[MainViewController alloc] initWithNibName:@"MainViewController_iPad" bundle:nil] autorelease];
        }
        self.window.rootViewController = self.mainViewController;
        [self.window makeKeyAndVisible];
        return YES;
    }
    

    will work, while

    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
    {
        self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
        // Override point for customization after application launch.
        if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
            self.mainViewController = [[[MainViewController alloc] initWithNibName:@"MainViewController_iPhone" bundle:nil] autorelease];
        } else {
            self.mainViewController = [[[MainViewController alloc] initWithNibName:@"MainViewController_iPad" bundle:nil] autorelease];
        }
        self.window.rootViewController = self.mainViewController;
        [self.window makeKeyAndVisible];
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(checkRegister:) name:@"checkRegister" object:nil];
        return YES;
    }
    

    will not work if your data loading is done in MainControllerView viewDidLoad method.