父对象对象在插入新子对象时与多级关系传递一对多关系。 Ios核心数据

时间:2015-05-18 12:56:00

标签: objective-c multithreading core-data relationship one-to-many

我遇到了在后台保存coredata的问题。我正在实施以下模型:

  • MasterManagedObject(类型为NSPrivateQueueConcurrencyType)
  • MainManagedObjectContext(类型为NSMainQueueConcurrencyType&是MasterManagedObject的子代)
  • TemporaryManagedObjectContext(类型为NSPrivateQueueConcurrencyType&是MainManagedObjectContext的子代)

代码是:

- (NSManagedObjectContext *)masterManagedObjectContext {
    if (_masterManagedObjectContext) {
        return _masterManagedObjectContext;
    }
    NSPersistentStoreCoordinator *coordinator = [self storeCoordinator];
    if (coordinator != nil) {
        dime(@"Here in master context");
        _masterManagedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
        [_masterManagedObjectContext setPersistentStoreCoordinator:coordinator];
    }
    return _masterManagedObjectContext;
}

- (NSManagedObjectContext *)mainManagedObjectContext {
    if (_mainManagedObjectContext) {
        return _mainManagedObjectContext;
    }

    _mainManagedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
    [_mainManagedObjectContext setParentContext:self.masterManagedObjectContext];
    return _mainManagedObjectContext;
}

+ (NSManagedObjectContext *)temporaryWorkerContext {

    NSManagedObjectContext *tempMOContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
    tempMOContext.parentContext = [[DDPersist manager] mainManagedObjectContext];
    return tempMOContext;
}

保存上下文:

+ (void)saveTempContext:(NSManagedObjectContext *)context {
    NSError *error;
    [context save:&error];
    if (!error) {
        [[DDPersist manager] saveMainContext];
        dime(@"Temp Context Saved");
    } else {
        dime(@"Temp Context Error  = %@",error);
    }
}

- (void)saveMainContext {
    [[[DDPersist manager] mainManagedObjectContext] performBlock:^{
        NSError *error = nil;
        [[[DDPersist manager] mainManagedObjectContext] save:&error];
        if(!error){
            //Write to disk after saving on the main UI context
            [[DDPersist manager] saveMasterContext];
            dime(@"main Context Saved");
        } else {
            dime(@"Main Context Error  = %@",error);
        }
    }];
}

- (void)saveMasterContext {
    [self.masterManagedObjectContext performBlock:^{
        NSError *error = nil;
        [self.masterManagedObjectContext save:&error];
        if(error){
            dime(@"Master Context Saved");
        } else {
            dime(@"Master Context Error  %@", error);
            if([NSThread isMainThread]) {
                dime(@"Master Context Error NOT ON BACKGROUND CONTEXT! WILL AUTOMATICALLY PERSIST ON MAIN CTX!");
            }
        }
    }];
}

我使用上面的方法在后台线程中创建新的spaceChecklistItems对象,如下所示:
    // space是具有一对多关系的spaceCheckListItem的父级。

                    __block NSManagedObjectID *spaceObjectID = [space objectID];
                    //Background thread starts here 
                    [DDPersist performTaskOnBackgroundCtxWithParentChildScheme:^(NSManagedObjectContext *bgCtx) {

                        Space *localSpace = (Space*)[bgCtx objectWithID:spaceObjectID];

                        for(NSDictionary * spaceChecklistItemDict in spaceChecklistItems) {
                            SpaceChecklistItem * spaceChecklistItem = [SpaceChecklistItemService importSpaceChecklistItem:spaceChecklistItemDict space:localSpace];
                            NSAssert(spaceChecklistItem, @"invalid SpaceChecklistItem at import!");
                            if(!spaceChecklistItem) continue;

                        }
                        [bgCtx obtainPermanentIDsForObjects:bgCtx.insertedObjects.allObjects error:nil];

                        [DDPersist saveTempContext:bgCtx];
                    }];

后台上下文中使用的方法(importSpaceChecklistItem)如下:

+ (SpaceChecklistItem*)importSpaceChecklistItem:(NSDictionary*)itemDict space:(Space*)space {

NSNumber *spaceChecklistItemId  = [itemDict objectForKey:@"id"];

NSString * inspectionStatus ;
if ([itemDict objectForKey:@"inspectionStatus"]) {
    inspectionStatus = [itemDict objectForKey:@"inspectionStatus"];
} else {
    inspectionStatus = @"UNDECIDED";
}

NSString * notes = [itemDict objectForKey:@"notes"];
MOC * ctx = space.managedObjectContext;

SpaceChecklistItem * spaceChecklistItem = [NSEntityDescription insertNewObjectForEntityForName:NSStringFromClass([SpaceChecklistItem class])
                                                                        inManagedObjectContext:ctx];


spaceChecklistItem.spaceChecklistItemId = spaceChecklistItemId;
spaceChecklistItem.space = space;// This is the relationship saving & not working.
spaceChecklistItem.inspectionStatus = inspectionStatus;
spaceChecklistItem.notes=notes;
spaceChecklistItem.sync = @NO;    
return spaceChecklistItem;
}

主要问题是性能问题。我想从上面加速循环:for(NSDictionary * spaceChecklistItemDict in spaceChecklistItems)。并希望将所有处理成背景。此for循环可能包含超过50000次迭代。这通常需要时间(约3分钟)保存到coredata.Data是保存,如果我使用单线程&在main(不是主上下文)的单线程子节点中保持循环。但这种一对多的关系给了我一些问题&我很长时间都在苦苦挣扎。

我读了很多stackoverflow问题&很多其他文章。但是不能解决这个问题。任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:0)

你有没有运行仪器?

运行Time Profiler并查看花费最多时间的内容。

将该跟踪发布到您的问题中,以便其他人也能看到它。