简体   繁体   中英

CoreData stack [child(background )/parent(thread 1 )] setup mergeChangesFromContextDidSaveNotification not updating UI(tableview)

quick question. I have a core data stack(child/parent)contexts. The child fetches json objs and parses them then saves them up to the parent,and when the count is 20 parent gets main thread and saves ...All works fine. However in my tableview i end up having to refetch the whole db every time! My fetchcount and duration is huge do to this, can any one give me some ideas? Iam all out thanks in advance! Also for some reason [[[SharedStore ShareStoreManager]getMasterContext] reset] works fine ... just not mergeChangesFromContext!

NSNotificationCenter *mergeNotification = [NSNotificationCenter defaultCenter];
[mergeNotification addObserver:self
                      selector:@selector(mergeChanges:) 
                          name:NSManagedObjectContextDidSaveNotification 
                        object:[[SharedStore ShareStoreManager]getMasterContext]]



-(void)mergeChanges:(NSNotification *)notification {
     [[[SharedStore ShareStoreManager]getMasterContext] mergeChangesFromContextDidSaveNotification:notification];
     [self.tableView layoutIfNeeded];
     [self.tableView reloadData];
}  

EDIT: I even went in to the context object and saw Inserted items that were not being merged so i went in there forced it but still no luck HELP!!!

for (User *user in [[notification.userInfo objectForKey:@"inserted"] allObjects]) {
        [[[SharedStore ShareStoreManager]getMasterContext] refreshObject:user mergeChanges:YES];
    }
[self.tableView reloadSections:[NSIndexSet indexSetWithIndex:0] withRowAnimation:UITableViewRowAnimationFade];
}

I'd reconsider your design and use a NSFetchedResultsController to do the fetching of your objects. What's great about using that class for your data source is that it will automatically get notifications when things change in its managed object context. By implementing the delegate callbacks for it, you can have your tableview respond to changes in the fetched results controller's data by inserting, deleting, moving, modifying the appropriate rows in the table view.

Here's a tutorial outlining step by step how to hook it all up.

Edit: Looking at your code, when you add the observer, you are only listening for saves that occur with your master context. If you are using a separate context to do your background processing, this notification will only get published for that background context, thus not triggering your observer. The only way your main context will trigger that notification is if you merge the background context with the main thread context and save the main thread context.

Your core data stack class should have its own observer, listening for all save events:

[[NSNotificationCenter defaultCenter] addObserver:sharedController
                                         selector:@selector(contextDidSave:)
                                             name:NSManagedObjectContextDidSaveNotification
                                           object:nil];

It should then merge the changes occurring on different threads and contexts on the main thread :

- (void)contextDidSave:(NSNotification *)notification {
    if (![NSThread isMainThread]) {
        dispatch_async(dispatch_get_main_queue(), ^{
            [self contextDidSave:notification];
        });
    } else {
        [self.managedObjectContext mergeChangesFromContextDidSaveNotification:notification];
    }
}

Note here that we're making sure that we perform the merge on the main thread, since the main context was created on the main thread and is not thread safe. Once the merge is completed, notifications will go out to observers, such as an NSFetchedResultsController which will then trigger its own delegate callbacks, giving you the opportunity to refresh the UI.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM