NSManagedObjectContext:如何更新主上下文

dhr*_*hrm 3 core-data objective-c nsmanagedobjectcontext

我有一个使用Core Data和默认AppDelegate的项目.我在我的代码中有以下线程,其中WSObject下载了我的NSManagedObject的图像.正如您将注意到的,我正在NSManagedObjectContext为此后台线程创建一个新的.我试图在网上阅读不同的文档和其他论坛主题,但是在我的对象保存在后台上下文中之后,我无法理解如何在AppDelegate中通知我的主要上下文.

- (void) downloadImageForObjectID:(NSManagedObjectID*)objectID {
    dispatch_queue_t imageDownloaderQueue = dispatch_queue_create("imagedownloader", NULL);
    dispatch_async(imageDownloaderQueue, ^{
        NSManagedObjectContext *context = [[NSManagedObjectContext alloc] init];
        context.persistentStoreCoordinator = [(AppDelegate *)[[UIApplication sharedApplication] delegate] persistentStoreCoordinator];
        context.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy;

        WSObject *item = (WSObject*)[context objectWithID:objectID];
        item.image.data = [item.image download];

        if ([context hasChanges]) {
            NSError *error = nil;
            [context save:&error];
        }
    });
    dispatch_release(imageDownloaderQueue);
}
Run Code Online (Sandbox Code Playgroud)

有人可以告诉我该方法和AppDelegate要添加什么才能使其正常工作?据我所知,NSManagedObjectContextDidSaveNotification当我在后台线程中保存上下文时会发送一个.我应该向AppDelegate添加什么代码来收听此通知以及收到通知时该怎么做?

EDIT1: 我已将观察者添加到后台线程中.

if ([context hasChanges]) {
    NSError *error = nil;


    NSManagedObjectContext *mainContext = [(AppDelegate *)[[UIApplication sharedApplication] delegate] managedObjectContext];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(mergeHandler:) name:NSManagedObjectContextDidSaveNotification object:mainContext];

    [context save:&error];

    [[NSNotificationCenter defaultCenter] removeObserver:self name:NSManagedObjectContextDidSaveNotification object:mainContext];
}
Run Code Online (Sandbox Code Playgroud)

但是mergeHandler从未调用过AppDelegate.

gsc*_*ler 12

在使用您注册的AppDelegate类定义的通知处理程序中NSManagedObjectContextDidSaveNotification,您只需执行以下操作:

- (void)myManagedObjectContextDidSaveNotificationHander:(NSNotification *)notification
{
    // since we are in a background thread, we should merge our changes on the main
    // thread to get updates in `NSFetchedResultsController`, etc.
    [self.managedObjectContext performSelectorOnMainThread:@selector(mergeChangesFromContextDidSaveNotification:) withObject:notification waitUntilDone:NO];
}
Run Code Online (Sandbox Code Playgroud)

假设self.managedObjectContext是指你的主NSManagedObjectContext,那就是它.

最简单的可能是在保存之前注册您的上下文,并在之后注销:

    if ([context hasChanges]) {
        NSError *error = nil;

       [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(myManagedObjectContextDidSaveNotificationHander:) name:NSManagedObjectContextDidSaveNotification object:context];

       [context save:&error];

       [[NSNotificationCenter defaultCenter] removeObserver:self name:NSManagedObjectContextDidSaveNotification object:context];
    }
Run Code Online (Sandbox Code Playgroud)