NSFetchedResultsController does not update TableView after UIManagedDocuments gets new data

限于喜欢 提交于 2020-01-03 03:34:13

问题


I am using a NSFetchedResultsController in combination with a UIManagedDocument which gets updated in an background thread.

I have set up the NSFetchedResultsController exactly as described in this tutorial: How To Use NSFetchedResultsController

I have set the delegate _fetchedResultsController.delegate = self and the protocol for my view controller to NSFetchedResultsControllerDelegate.

My code works fine when it loads the data after launch. However, the NSFetchedResultsController does not update the TableView whenever it has processed and saved the data in the background thread. In particular, the NSFetchedResultsController's delegate methods -controllerWillChangeContent:controlleretc. are never being called.

I have double-checked that the SQLite database contains the data correctly. This is how I process and save the data in the view controller:

[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];
    }];

How can I get the NSFetchedResultsController to update the TableView automatically when the underlying data changes?

Thank you for your help!


回答1:


I think that reason is in managedObjectContext. You make changes in background, and NSFetchedResultsController fetches from the main one. So you need to merge changes to that one context by adding an observer of changes in context

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

Here is a great tutorial by Marcus Zarra - The Guru of Core Data) Hope that helps. http://www.cimgf.com/2011/08/22/importing-and-displaying-large-data-sets-in-core-data/




回答2:


I would suggest, when using UIManagedDocument, that you make your background context a child of the main context.

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

Now, you can do what you want in the background context, and when you want to save the background context, the changes will be stuffed into the main context. Of course, you will still need to save the UIManagedDocument, but that is done "seamlessly" in the background again, via setting the ChangeDone count.

[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];
    }];
}];

Now, your background context just goes away, your main context sees the changes, and the document is saved.



来源:https://stackoverflow.com/questions/11192916/nsfetchedresultscontroller-does-not-update-tableview-after-uimanageddocuments-ge

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!