我遇到了在后台保存coredata的问题。我正在实施以下模型:
代码是:
- (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问题&很多其他文章。但是不能解决这个问题。任何帮助将不胜感激。
答案 0 :(得分:0)
你有没有运行仪器?
运行Time Profiler并查看花费最多时间的内容。
将该跟踪发布到您的问题中,以便其他人也能看到它。