在UIManagedDocuments获取新数据后,NSFetchedResultsController不会更新TableView

时间:2012-06-25 16:02:21

标签: objective-c ios core-data ios5 nsfetchedresultscontroller

我正在使用NSFetchedResultsControllerUIManagedDocument结合使用,后者会在后台主题中更新。

我完全按照本教程中的描述设置了NSFetchedResultsController:How To Use NSFetchedResultsController

我已将代理_fetchedResultsController.delegate = self和我的视图控制器的协议设置为NSFetchedResultsControllerDelegate

我的代码在启动后加载数据时工作正常。但是,NSFetchedResultsController 无论何时处理并保存后台线程中的数据,都不会更新TableView 。特别是NSFetchedResultsController的委托方法-controllerWillChangeContent:controller等。永远不会被召唤。

我仔细检查过SQLite数据库是否包含正确的数据。 这是我在视图控制器中处理和保存数据的方式:

[backgroundContext performBlock:^{
        [company parseAttributesFrom:xmlStr inManagedObjectContext:backgroundContext]; //self.managedDocument.managedObjectContext

        NSError *error = nil;
        [backgroundContext save:&error];
         if (error) NSLog(@"error: %@",error.localizedDescription);
        [self.managedDocument.managedObjectContext performBlock:^{
            NSError *error = nil;
            [self.managedDocument.managedObjectContext save:&error];
            if (error) NSLog(@"error: %@",error.localizedDescription);
        }];
        [self.managedDocument saveToURL:self.managedDocument.fileURL forSaveOperation:UIDocumentSaveForOverwriting completionHandler:NULL];
        [self.managedDocument updateChangeCount:UIDocumentChangeDone];
    }];

当底层数据发生变化时,如何让NSFetchedResultsController自动更新TableView?

感谢您的帮助!

2 个答案:

答案 0 :(得分:2)

我认为原因在于managedObjectContext。您在后台进行了更改,并从主要内容中进行了NSFetchedResultsController提取。因此,您需要通过添加上下文中的更改观察器来将更改合并到该上下文

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(contextChanged:) name:NSManagedObjectContextDidSaveNotification object:nil];

这是Marcus Zarra的伟大教程 - 核心数据的大师) 希望有所帮助。 http://www.cimgf.com/2011/08/22/importing-and-displaying-large-data-sets-in-core-data/

答案 1 :(得分:1)

在使用UIManagedDocument时,我建议您将背景上下文作为主要上下文的子项。

backgroundContext = [[NSManagedContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
backgroundContext.parent = self.managedDocument.managedObjectContext;

现在,您可以在后台上下文中执行所需操作,并且当您想要保存背景上下文时,更改将填充到主上下文中。当然,您仍然需要保存UIManagedDocument,但通过设置ChangeDone计数,可以在后台再次“无缝地”完成。

[backgroundContext performBlock:^{
    [company parseAttributesFrom:xmlStr inManagedObjectContext:backgroundContext]; //self.managedDocument.managedObjectContext

    NSError *error = nil;
    [backgroundContext save:&error];
     if (error) NSLog(@"error: %@",error.localizedDescription);

    // NOTE: Now, the changes have been pushed into the main context of your document.
    // DO NOT call save directly on the managed document context.
    [self.managedDocument.managedObjectContext performBlock:^{
        [self.managedDocument updateChangeCount:UIDocumentChangeDone];
    }];
}];

现在,您的背景上下文消失了,您的主要上下文会看到更改,并且文档已保存。