2012-02-10 63 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

相關問題