Search code examples
objective-cnsnotification

Why using NSNotification argument


Here is the code in main.m

[[NSNotificationCenter defaultCenter]addObserver:logger selector:@selector(zoneChange:) name:NSSystemTimeZoneDidChangeNotification object:nil];

here is the code in .h file

-(void)zoneChange:(NSNotification *)note;

Can someone tell me why zoneChange method take NSNotification as an argument? How do we know what argument does this method take when trying to declare it to be used by the method mentioned in the main.m file above?

Also I did some research on the class reference and found out this for the selector parameter

Selector that specifies the message the receiver sends notificationObserver to notify it of the notification posting. The method specified by notificationSelector must have one and only one argument (an instance of NSNotification).

Please explain. Thanks


Solution

  • Imagine you have a controller that has two table views:

    @interface MyController : NSViewController <NSTableViewDelegate>
    
    @property(nonatomic,weak) IBOutlet NSTableView *tableView1;
    @property(nonatomic,weak) IBOutlet NSTableView *tableView2;
    
    @end
    

    And controller is set as delegate for both table views. Now you want to track changes in selections of both tables. You implement tableViewSelectionDidChange: delegate method, but when it is called, how do you know which table view did change it's selection? Here comes the notification argument. It's object property points to table view that did sent this notification, and you can easily differentiate between two. Also it may contain userInfo dictionary, for example NSTableViewColumnDidResizeNotification contains a NSTableColumn and NSOldWidth keys in there.

    In described case, the method responding to notification was called under delegate idiom, but in other scenarios (observed notification, target-action, etc.) you also sometimes must differentiate objects that caused a method call.

    @implementation MyController
    
    ...
    
    - (void)tableViewSelectionDidChange:(NSNotification *)notification
    {
        if ([notification object] == self.tableView1)
            NSLog(@"selection changed in table 1");
    
        else if ([notification object] == self.tableView2)
            NSLog(@"selection changed in table 2");
    
        else
            NSLog(@"selection changed in unknown table (???)");
    }
    
    - (void)buttonDidClick:(id)sender
    {
        NSLog(@"some button did click. which? %@", sender);
    }
    
    @end