NSNotificationCenter: addObserver that is not self

2019-06-03 04:44发布

问题:

Here's the question:

Can one View Controller add another View Controller as an Observer to the defaultCenter before the second view has been loaded?

I have a model class that creates a NSURLSession, grabs some data, builds an array, and sends notifications that it's done (along with a pointer to the array).

My app loads with a Map View that instantiates the model, calls the method to create the array, listens for the notification, and drops pins using the array.

I have a Table View tab that I want to load using the array built by the map.

Can my Map View add my Table View Controller as an observer before the Table View is loaded?

Something like:

[[NSNotificationCenter defaultCenter] addObserver: TableViewController ...

Thanks for any insight. I'm figuring this out as I go.

-----------------EDIT--------------------

viewDidLoad from MapViewController:

- (void)viewDidLoad
{
  [super viewDidLoad];
  _mapView.delegate = self;
  _model = [[WikiModel alloc] init];
  _lastArticleUpdateLocation = [[CLLocation alloc] initWithLatitude:0 longitude:0];
  _lastUpdateUserLocation    = [[CLLocation alloc] initWithLatitude:0 longitude:0];

  // Listen for WikiModel to release updates.
  [[NSNotificationCenter defaultCenter] addObserver:self
                                           selector:@selector(reloadData:)
                                               name:@"Array Complete"
                                             object:_model];

//table view listener attempt ...
UITableViewController *tvc = [self.storyboard instantiateViewControllerWithIdentifier:@"tableViewController"];

[[NSNotificationCenter defaultCenter] addObserver:tvc
                                         selector: @selector(updateDataSource:)
                                             name:@"Array Complete"
                                           object:nil];
[self.navigationController pushViewController:tvc animated:YES];

}

From the TableViewController:

- (void)viewDidLoad
{
  [super viewDidLoad];

  // Listen for WikiModel to release updates.
    /*
  [[NSNotificationCenter defaultCenter] addObserver:self
                                           selector:@selector(updateDataSource:)
                                               name:@"Array Complete"
                                             object:nil];*/
}

-(void)updateDataSource:(NSNotification *)notification
{
  _wikiEntries = [[notification userInfo] objectForKey:@"wikiEntryArray"];
  [self.tableView reloadData];
    NSLog(@"************received***********");
}

回答1:

This is possible as long as you pass the pointer to your view controller as the observer. Here's an example:

//Go to the detail view
VC2ViewController *dvc = [self.storyboard instantiateViewControllerWithIdentifier:@"VC2ViewController"]; //ID specified in the storyboard
[[NSNotificationCenter defaultCenter] addObserver:dvc selector:@selector(notificationReceived:) name:@"MyNotification" object:nil];
[self.navigationController pushViewController:dvc animated:YES];

Then, you can post your notification as usual:

[[NSNotificationCenter defaultCenter] postNotificationName:@"MyNotification" object:nil];

I just tested the above code and it worked fine for me, the following function was called in my detail view controller:

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

    NSLog(@"RECEIVED");
}