在子上下文中保存核心数据不起作用
Posted
技术标签:
【中文标题】在子上下文中保存核心数据不起作用【英文标题】:Core data saving on child context not working 【发布时间】:2016-06-28 11:22:50 【问题描述】:对于 coredata 中的并发,我使用父子 MOC 概念,其中父上下文为NSMainQueueConcurrencyType
,子上下文为NSPrivateQueueConcurrencyType
,下面是代码
- (NSManagedObjectContext *)managedObjectContext
if (managedObjectContext != nil)
return managedObjectContext;
NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
if (coordinator != nil)
managedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];// DONE to avoid crash when the app auto logs out
managedObjectContext.persistentStoreCoordinator = coordinator;
return managedObjectContext;
-(NSManagedObjectContext *)getPrivateMOC
NSManagedObjectContext *private = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
[private setParentContext:[self managedObjectContext]];
return private;
-(void)storeCustomerData:(NSArray *)custData
NSManagedObjectContext *currentbgContext = [self getPrivateMOC];
[currentbgContext performBlock:^
for (NSDictionary *jsonObject in custData)
CustomerEntity *custEntity = [NSEntityDescription insertNewObjectForEntityForName:@"CustomerEntity" inManagedObjectContext:currentbgContext];
custEntity.fname = [jsonObject field:@"fname"];
custEntity.lname = [jsonObject field:@"lname"];
NSError *error = nil;
if (![currentbgContext save:&error])
NSLog(@"Error saving context: %@\n%@", [error localizedDescription], [error userInfo]);
//abort();
];
如果我在方法 storeCustomerData
中使用父上下文,它可以工作,但使用子上下文 getPrivateMOC()
则不行。
如果我遗漏了什么,请告诉我
【问题讨论】:
查看这个答案***.com/questions/12271464/… 【参考方案1】:我想我明白你的问题了,请试试下面的代码
// Used to propegate saves to the persistent store (disk) without blocking the UI
- (NSManagedObjectContext *)masterManagedObjectContext
if (_masterManagedObjectContext != nil)
return _masterManagedObjectContext;
NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
if (coordinator != nil)
_masterManagedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
_masterManagedObjectContext.retainsRegisteredObjects = YES; //TO-DO : Need update this later
[_masterManagedObjectContext performBlockAndWait:^
[_masterManagedObjectContext setPersistentStoreCoordinator:coordinator];
// [_masterManagedObjectContext setUndoManager:nil];
];
return _masterManagedObjectContext;
// Return the NSManagedObjectContext to be used in the background during sync
- (NSManagedObjectContext *)backgroundManagedObjectContext
if (_backgroundManagedObjectContext != nil)
return _backgroundManagedObjectContext;
NSManagedObjectContext *masterContext = [self masterManagedObjectContext];
if (masterContext != nil)
_backgroundManagedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
[_backgroundManagedObjectContext performBlockAndWait:^
[_backgroundManagedObjectContext setParentContext:masterContext];
];
return _backgroundManagedObjectContext;
// Return the NSManagedObjectContext to be used in the background during sync
- (NSManagedObjectContext *)newManagedObjectContext
NSManagedObjectContext *newContext = nil;
NSManagedObjectContext *masterContext = [self masterManagedObjectContext];
if (masterContext != nil)
newContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
[newContext performBlockAndWait:^
[newContext setParentContext:masterContext];
];
return newContext;
- (void)saveMasterContext
[self.masterManagedObjectContext performBlockAndWait:^
NSError *error = nil;
BOOL saved = [self.masterManagedObjectContext save:&error];
if (!saved)
// do some real error handling
//NSLog(@"Could not save master context due to %@", error);
];
- (void)saveBackgroundContext
[self.backgroundManagedObjectContext performBlockAndWait:^
NSError *error = nil;
BOOL saved = [self.backgroundManagedObjectContext save:&error];
if (!saved)
// do some real error handling
//NSLog(@"Could not save background context due to %@", error);
];
static dispatch_queue_t coredata_background_save_queue;
dispatch_queue_t background_save_queue()
if (coredata_background_save_queue == NULL)
coredata_background_save_queue = dispatch_queue_create("com.magicalpanda.coredata.backgroundsaves", 0);
return coredata_background_save_queue;
- (void)saveDataInBackgroundWithContext:(void(^)(NSManagedObjectContext *context))saveBlock
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^
[self saveDataInContext:saveBlock];
);
- (void)saveDataInContext:(void(^)(NSManagedObjectContext *context))saveBlock
NSManagedObjectContext *context = [[EFCoreDataController sharedInstance] backgroundManagedObjectContext];
[context setMergePolicy:NSMergeByPropertyObjectTrumpMergePolicy];
[[self objectContext] setMergePolicy:NSMergeByPropertyStoreTrumpMergePolicy];
// [[self objectContext] observeContext:context]; //step 3
// block(context); //step 4
if ([context hasChanges]) //step 5
NSError *e;
[[self objectContext] save:&e]; //MagicalRecord will dump errors to the console with this save method
【讨论】:
以上是关于在子上下文中保存核心数据不起作用的主要内容,如果未能解决你的问题,请参考以下文章
核心数据:后台更新 NSManagedObjectContext 在保存时不起作用