UVableView中KVO观察模型更改的最佳实践

时间:2013-12-11 13:42:18

标签: ios iphone objective-c uitableview key-value-observing

让我们设想一个基本的iPhone应用程序,其中包含用于显示人员列表的表格视图以及用于更改导航控制器中嵌入的人员姓名的详细信息视图。

我正在使用KVO在我的表格视图控制器中收到通知,在详情控制器中更改了某个人的姓名。

我的问题是何时/何处添加和删除我的表视图控制器作为每个人对象的name的观察者。

我的方法:

@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"];
    }
}

由于导航控制器,事情有点棘手,因为从视图层次结构中删除视图时不会调用tableView: didEndDisplayingCell。我无法删除viewWillDisappear:中的观察者,因为当用户从详细信息控制器返回时,我仍然需要观察人物对象的变化。

删除dealloc中的观察者似乎有效。我的问题:这是正确的方法吗?

1 个答案:

答案 0 :(得分:0)

通常你应该分别在viewWillAppear / viewWillDisappear方法上调用addObserver / removeObserver,因为dealloc方法与这个调用不平衡(我的意思是可以比上面的方法调用几次)。也许最好的解决方案之一是使用NSFetchedResultsController来跟踪对数据源的任何更改。