Objective c 插入新的子对象时,父对象到子对象传递一对多关系和多级关系。Ios核心数据
我在后台保存coredata时遇到问题。我正在实施以下模型: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的子级
- 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上从实际代码复制到此处并删除额外代码时错过了该行。我现在更新了代码。我可以添加,没问题。但我目前在保存上下文时遇到了一些问题。仪器是完全不同的东西。如果我能以某种方式解决这个上下文保存问题,那么我认为它会解决所有问题。我的关系有问题。仪器是解决性能问题的工具。这是你第一个去看东西为什么慢的地方。如果不产生错误,则需要在仪器中查看此保存问题。否则你只是在浪费时间猜测和假设。这甚至可能不是核心数据问题,可能是线程问题,也可能是数据问题。在时间分析器下运行它之前,您不会知道。说真的,这是第一步。