核心数据更新关系实体与并发的bug

时间:2014-02-18 11:15:52

标签: ios iphone core-data nsmanagedobjectcontext

所以我使用http://www.cocoanetics.com/2012/07/multi-context-coredata/实现了Core Data Concurrency我为每个输入数据的对象实现了单独的私有MOC,它运行良好,我在main线程上使用FRC获取数据的mainMOC,这是我遇到的唯一问题所以远是更新关系实体。

所以,如果我有摄影师&照片实体一对多关系“一个摄影师可以有多张照片”,当用户上传新照片时,我用以下代码更新照片实体和摄影师“关系”......'注意:这是一个临时代码'

+ (Photo *)didUploadNewPhoto:(PhotoClass *)photoObj inManagedObjectContext:(NSManagedObjectContext *)context
{
    Photo *photo = nil;

    NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"Photos"];
    request.predicate = [NSPredicate predicateWithFormat:@"photoID = %@",photoObj.ID];

    NSError *error;
    NSArray *matches = [context executeFetchRequest:request error:&error];

    if (!matches || error || ([matches count] > 1)) {
        //handle error

    } else if ([matches count]) {
        photo = [matches firstObject];

    } else {

        photo.title = @"";
        photo.timeStamp = @"";
        photo.photographer = [Photographer updatePhotographerClass:photoObj inManagedObjectContext:context];

        NSError *error = nil;
        if (![context save:&error]) {
            //handle Error
        }
    return photo;
}


+ (Photographer *)updatePhotographerClass:(Photo *)photoObj inManagedObjectContext:(NSManagedObjectContext *)context
{
    Photographer *photographer = nil;

    NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"Photographer"];
    request.predicate = [NSPredicate predicateWithFormat:@"PhotographerID= %@",photoObj.PhotographerID];

    NSError *error;
    NSArray *matches = [context executeFetchRequest:request error:&error];

    if (!matches || error || ([matches count] > 1)) {
        //handle error

    } else if ([matches count]) {

        photographer = [matches firstObject];
        photographer.didUploadPhoto = @YES;

    }
    return photographer;
}

我面临的问题是FRC确实更新了照片,但它没有更新摄影师“didUploadPhoto”中的布尔值,是否有些东西我可能会丢失?如果我在主线程上使用上下文使用相同的代码,它工作得很好......但是如果我使用后台线程将其更改为输入数据,它会更新Photo但不会更新摄影师。

更新

这是我如何使用后台/私人MOC调用UploadPhoto方法的示例代码

NSManagedObjectContext *tempContext = self.contextStore.newPrivateContext;
[tempContext performBlock:^{
    [Photos didUploadNewPhoto:photoObj inManagedObjectContext:tempContext];
}];

这就是我创建privateContext的方式

- (NSManagedObjectContext*)newPrivateContext
{
    NSManagedObjectContext* context = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
    context.persistentStoreCoordinator = self.persistentStoreCoordinator;
    [context setUndoManager:nil];

    return context;
}

以下是我用来合并更改的通知......

- (void)setupSaveNotification
{
    [[NSNotificationCenter defaultCenter] addObserverForName:NSManagedObjectContextDidSaveNotification
                                                      object:nil
                                                       queue:nil
                                                  usingBlock:^(NSNotification* note) {
                                                      NSManagedObjectContext *moc = self.mainContext;
                                                      if (note.object != moc) {
                                                          [moc performBlock:^(){
                                                              [moc mergeChangesFromContextDidSaveNotification:note];
                                                          }];
                                                      }
                                                  }];
}

0 个答案:

没有答案
相关问题