NSFetchedResultsControllerDelegate未触发

时间:2009-08-24 00:08:01

标签: iphone cocoa-touch core-data nsfetchedresultscontroller

我无法弄清楚为什么,在我的生活中,当我向基础数据存储添加数据时,NSFetchedResultsControllerDelegate方法不会触发。如果我重新启动iPhone应用程序,数据会立即显示。

我已经将UITableViewController子类化并符合NSFetchedResultsControllerDelegate:

@interface ProjectListViewController : UITableViewController <NSFetchedResultsControllerDelegate> {
    NSFetchedResultsController* fetchedResultsController_;
    NSManagedObjectContext* managedObjectContext_;
}

我实例化NSFetchedResultsController并将委托设置为self:

// Controller
fetchedResultsController_ = [[NSFetchedResultsController alloc] initWithFetchRequest:request
    managedObjectContext:self.managedObjectContext 
                                                                  sectionNameKeyPath:@"Client" 
                                                                           cacheName:@"ProjectsCache"];
fetchedResultsController_.delegate = self;

我实现了委托方法:

- (void)controllerWillChangeContent:(NSFetchedResultsController*)controller {
    NSLog(@"ProjectListViewController.controllerWillChangeContent");
    // The fetch controller is about to start sending change notifications, so prepare the table view for updates.
    [self.tableView beginUpdates];
}

- (void)controllerDidChangeContent:(NSFetchedResultsController*)controller { ... }
- (void)controller:(NSFetchedResultsController*)controller didChangeObject:(id)anObject atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type newIndexPath:(NSIndexPath *)newIndexPath { ... }
- (void)controller:(NSFetchedResultsController *)controller didChangeSection:(id<NSFetchedResultsSectionInfo>)sectionInfo atIndex:(NSUInteger)sectionIndex forChangeType:(NSFetchedResultsChangeType)type { ... }

我创建了我想保存的实体:

Project* newProject = [NSEntityDescription insertNewObjectForEntityForName:@"Project" inManagedObjectContext:self.managedObjectContext];
ProjectDetailViewController* detail = [[ProjectDetailViewController alloc] initWithStyle:UITableViewStyleGrouped 
                                                                                delegate:self 
                                                                                selector:@selector(finishedAdding:) 
                                                                                 project:newProject];

后来,我保存了它:

- (void)save {
    // NSLog(@"ProjectDetailViewController.save");
    self.project.name = projectNameTextField_.text; 
    NSError* error;
    BOOL b = [self.project.managedObjectContext save:&error];
    if (!b) {
        NSLog(@"Error saving project!");
    } else {
        NSLog(@"Project was successfully saved.");
        [delegate_ performSelector:selector_ withObject:self.project];
    }
    [self dismissModalViewControllerAnimated:YES];
}

除了我的委托方法不会触发之外,一切正常。显然我的表视图没有得到更新,查看新数据的唯一方法是显式刷新或重新启动应用程序。

我查看了CoreData Recipe应用程序 - 但似乎无法找到我所遗漏的内容。想法?

-Luther

2 个答案:

答案 0 :(得分:3)

如果我在创建原始sectionNameKeyPath时将fetchedResultsController_从@“客户端”更改为nil,则Project实体创建保存确实调用了委托方法!

fetchedResultsController_ = 
    [[NSFetchedResultsController alloc] initWithFetchRequest:request
                                        managedObjectContext:self.managedObjectContext 
                                          sectionNameKeyPath:nil
                                                   cacheName:@"ProjectsCache"];

经过严格审查,这就是CoreData Recipes示例所做的。随着我的数据变得越来越复杂 - 我想我将需要这个参数来帮助将结果分成几个部分,但是现在,很高兴看到调用委托处理程序。

答案 1 :(得分:1)

我对上面的内容看起来好像你正在使用2个NSManagedObjectContexts,一个在ProjectListViewController中,并在ProjectDetailViewController中分开一个(我假设它是在那里创建的,因为我没有看到它传入。

当您保存一个上下文时,它不会自动将更改传播到另一个上下文,因此保存ProjectDetailViewController中的更改不会导致更改出现在ProjectListViewController的上下文中,这意味着该更改没有任何更改来告诉委托它

如果要在上下文之间推送更改,请查看NSManagedObjectContextDidSaveNotification和mergeChangesFromContextDidSaveNotification :(它们是NSManagedObjectContext documentation的结尾)。