NSFetchedResultsController委托仅在第一次应用程序启动时触发方法

时间:2012-02-10 15:44:00

标签: ios core-data nsfetchedresultscontroller

对不起我糟糕的英语。 我的iOS应用程序中存在很大问题。应用程序具有由Core Data管理的大型数据库。我有许多用于显示此数据的TableView控制器。数据库中的任何更改都应显示在tableview中。可以通过实现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;
    }

}

1 个答案:

答案 0 :(得分:2)

这似乎是NSFetchedResultsController执行的正确方式 - 响应模型层的更改(即[managedObjectContext save])。

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