Objective c 插入新的子对象时,父对象到子对象传递一对多关系和多级关系。Ios核心数据

Objective c 插入新的子对象时,父对象到子对象传递一对多关系和多级关系。Ios核心数据,objective-c,multithreading,core-data,relationship,one-to-many,Objective C,Multithreading,Core Data,Relationship,One To Many,我在后台保存coredata时遇到问题。我正在实施以下模型: MasterManagedObject(类型为NSPrivateQueueConcurrencyType) MainManagedObjectContext(类型为NSMainQueueConcurrencyType&是MasterManagedObject的子级) 临时ManagedObjectContext(类型为NSPrivateQueueConcurrencyType&是MainManagedObjectContext的子级

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

  • MasterManagedObject(类型为NSPrivateQueueConcurrencyType)
  • MainManagedObjectContext(类型为NSMainQueueConcurrencyType&是MasterManagedObject的子级)
  • 临时ManagedObjectContext(类型为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对象,如下所示:
//空间是具有一对多关系的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循环:for(NSDictionary*spaceChecklistItemDict in spaceChecklistItems)。并想把所有的处理都放到后台。此for循环可能包含50000次以上的迭代。这通常需要时间(大约3分钟)才能保存到coredata中。如果在main的单线程子线程(而不是主上下文)中使用单线程&keep for循环,则数据正在保存。但是这种一对多的关系给我带来了问题&我为此挣扎了很长时间


我读了很多问题和其他文章。但我不能把这类问题弄清楚。任何帮助都将不胜感激。

您运行过仪器吗

运行时间分析器,查看花费时间最多的是什么


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

似乎您没有在导入方法中创建任何
spaceChecklistItem
。@Mundi,很抱歉,我在stackOverFlow上从实际代码复制到此处并删除额外代码时错过了该行。我现在更新了代码。我可以添加,没问题。但我目前在保存上下文时遇到了一些问题。仪器是完全不同的东西。如果我能以某种方式解决这个上下文保存问题,那么我认为它会解决所有问题。我的关系有问题。仪器是解决性能问题的工具。这是你第一个去看东西为什么慢的地方。如果不产生错误,则需要在仪器中查看此保存问题。否则你只是在浪费时间猜测和假设。这甚至可能不是核心数据问题,可能是线程问题,也可能是数据问题。在时间分析器下运行它之前,您不会知道。说真的,这是第一步。