2012-02-10 62 views
1

对不起,我的英文很糟糕。 我在我的iOS应用程序中遇到大问题。应用程序拥有由Core Data管理的大型数据库。我有很多用于显示这些数据的TableView控制器。数据库中的任何改变都应该在tableview中显示。可以通过实现NSFetchedResultsController委托协议来实现。所有的实现都像书中一样简单。如果应用程序启动模拟器中第一次和我加入一些新的表条目旁边的委托方法成功地发射:NSFetchedResultsController仅在第一次启动应用程序时触发方法

– controllerWillChangeContent: 
– controller:didChangeObject:atIndexPath:forChangeType:newIndexPath: 
– controllerDidChangeContent: 

站经过调试和启动应用程序没有再次上市的方法被解雇。 他们只在[managedObjectContext save]操作执行后才会呼叫。

你有什么想法,为什么会发生这种情况?

源代码:

//IssueProfileViewController.h class implements NSFetchedResultController delegate methods 
- (NSFetchedResultsController*)fetchedResultsController{ 

    if (_fetchedResultsController == nil) { 

     NSManagedObjectContext *managedObjectContext = self.issue.managedObjectContext; 
     NSFetchRequest *aFetchRequest = [[NSFetchRequest alloc] init]; 
     NSEntityDescription *entity = [NSEntityDescription entityForName:@"IssueHistoryItem" inManagedObjectContext:managedObjectContext]; 
     [aFetchRequest setEntity:entity]; 

     NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"created" ascending:NO]; 
     NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil]; 

     //NSPredicate *predicate = [[NSPredicate predicateWithFormat:@"issue == %@ && isComment == NO", self.issue] retain]; 

      NSPredicate *predicate = [NSPredicate predicateWithFormat:@"issue == %@ && isComment == NO", self.issue]; 

     [aFetchRequest setSortDescriptors:sortDescriptors]; 
     [aFetchRequest setPredicate:predicate]; 

      NSFetchedResultsController *aFetchedResultsController = 
       [[NSFetchedResultsController alloc] initWithFetchRequest:aFetchRequest                        
        managedObjectContext:managedObjectContext 
        sectionNameKeyPath:nil 
        cacheName:nil]; 

     [aFetchRequest release]; 
     //[predicate release]; 
     [sortDescriptors release]; 
     [sortDescriptor release]; 
      _fetchedResultsController = aFetchedResultsController; 
      _fetchedResultsController.delegate = self; 
     } 

     return _fetchedResultsController; 
    } 


-(void)controllerWillChangeContent:(NSFetchedResultsController *)controller { 
    [self.tableView beginUpdates]; 
} 

-(void)controllerDidChangeContent:(NSFetchedResultsController *)controller { 
    [self.tableView endUpdates]; 
} 

-(void)controller:(NSFetchedResultsController *)controller 
    didChangeObject:(id)anObject 
     atIndexPath:(NSIndexPath *)indexPath 
    forChangeType:(NSFetchedResultsChangeType)type 
    newIndexPath:(NSIndexPath *)newIndexPath { 

    NSArray *paths; 
// NSIndexSet *section = [NSIndexSet indexSetWithIndex:[newIndexPath section]]; 

    NSIndexPath *cellContentIndexPath; 

    switch (type) { 
     case NSFetchedResultsChangeInsert: 
//   paths = [NSArray arrayWithObject:newIndexPath]; 
      if (![anObject isKindOfClass:[ChangeIssueDimensionValueHistoryItem class]]) { 
       cellContentIndexPath = [NSIndexPath indexPathForRow:newIndexPath.row inSection:newIndexPath.section]; 
       paths = [NSArray arrayWithObject:cellContentIndexPath]; 
       [self.tableView insertRowsAtIndexPaths:paths 
             withRowAnimation:UITableViewRowAnimationFade]; 

       [self sendMessageAboutObjectsCountChanged]; 
      } 

      break; 
     case NSFetchedResultsChangeDelete: 
      paths = [NSArray arrayWithObject:indexPath]; 
      [self.tableView deleteRowsAtIndexPaths:paths 
            withRowAnimation:UITableViewRowAnimationFade]; 
      [self sendMessageAboutObjectsCountChanged]; 
      break; 
     case NSFetchedResultsChangeMove: 
      [self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] 
             withRowAnimation:UITableViewRowAnimationFade]; 
      [self.tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] 
             withRowAnimation:UITableViewRowAnimationFade]; 
      break; 
     case NSFetchedResultsChangeUpdate: 
      [self configureCell:[self.tableView cellForRowAtIndexPath:indexPath] 
      withIssueHistoryItem:[self.fetchedResultsController objectAtIndexPath:indexPath]]; 
      break; 
     default: 
      break; 
    } 

} 

回答

2

这似乎是该NSFetchedResultsController执行适当的方式 - 响应于在模型层(即[managedObjectContext save])的变化。

在“响应更改”下的文档中:https://developer.apple.com/library/ios/#documentation/CoreData/Reference/NSFetchedResultsController_Class/Reference/Reference.html表示控制器不会显示更改,直到被管理对象的上下文收到processPendingChanges消息。该消息也可以手动触发。

+0

谢谢你的回答!但是如果我理解得当,当我添加新的实体到上下文时,它必须触发'processPendingChanges'?或不? – hex 2012-02-13 07:46:36

+1

是的,如果NSFetchedResultsController的NSManagedObjectContext接收到processPendingChanges,tableView应该更新。并且(在这里重申)当上下文被保存时,这自动发生。 – JacobFennell 2012-02-13 17:34:57

相关问题