Pregunta

Let's imagine a basic iPhone app with a table view to show a list of people and a details view to change the name of a person embedded in a navigation controller.

I'm using KVO to get notified in my table view controller that the name of a person was changed down in the details controller.

My question is when/where to add and remove my table view controller as observer for the name of each person object.

My approach:

@implementation PeopleTableViewController 

- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
    Person *person = ...; // person for index path

    [person addObserver:self forKeyPath:@"name" options:0 context:(__bridge void *)(PERSON_NAME_CTX)];
}

- (void)tableView:(UITableView *)tableView didEndDisplayingCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
    Person *person = ...; // person for index path

    [person removeObserver:self forKeyPath:@"name"];

    // This is not called when the view is removed from the hierarchy
    // Can't use viewDidDisappear: because we are using a navigation controller
    // and tableView:willDisplayCell: is not called when we return from the details controller
}

- dealloc {
    // See comment in didEndDisplayingCell:

    for (UITableViewCell *cell in self.tableView.visibleCells) {
        NSIndexPath *indexPath = [self.tableView indexPathForCell:cell];

        Person *person = ...; // person for index path

        [person removeObserver:self forKeyPath:@"name"];
    }
}

Due to the navigation controller things are a bit tricky, because tableView: didEndDisplayingCell is not called when the view is removed from the view hierarchy. I can't remove the observer in viewWillDisappear:, because when the user returns from the details controller I still need to observe the person objects for changes.

Removing the observer in dealloc seems to work. My question: is this the right way to do it?

¿Fue útil?

Solución

Usually you should call addObserver/removeObserver on viewWillAppear/viewWillDisappear methods respectively, because dealloc method is not balanced with this calls (I mean can be called few times than the methods above). Maybe one of the best solutions is use a NSFetchedResultsController in order to track any change to the data source.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top