2009-08-24 131 views
3

我不明白为什么,在我的生活中,当我向底层数据存储添加数据时,NSFetchedResultsControllerDelegate方法没有触发。如果我重新启动iPhone应用程序,数据立即显示。NSFetchedResultsControllerDelegate没有触发

我有子类的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食谱应用程序 - 但似乎无法找到我失踪的东西。思考?

-Luther

+0

路德,你可以确认实体和谓词你配置的NSFetchedResultsController? – ohhorob 2009-12-22 09:38:27

回答

3

如果我改变来自@“客户”的sectionNameKeyPath到零,当我创建原始fetchedResultsController_,无论是Project实体创作保存确实调用委托方法!

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

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

1

我上面读看起来像你正在使用2个NSManagedObjectContexts,一个在ProjectListViewController,并单独一个在ProjectDetailViewController(我假设,因为我没有看到它在传递,但它创造了那里。

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

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

+0

考虑到我看到的行为,您的观点确实有道理,是的,我已经能够成功地使用通知来合并更改,但是,我无法理解是'为什么'这是必要的。我错过了一些东西。 我使用相同的managedObjectContext来创建fetchedResultsController_,'newProject' 并且还保存'newProject'(上下文是从原始managedObjectContext创建的'newProject'的属性)。 [self.project.managedObjectContext save:&error]; 我认为委托方法应该在我创建AND时保存'newProject'时触发。 – 2009-08-24 04:36:13