我遇到了与我的核心数据实现和线程相关的问题。它在 iOS 7 上运行良好,但我无法在 iOS 6 上正确刷新主要上下文。
我有两个 NSPersistentStoreCoordinators 指向同一个数据库文件。然后我有一个主要上下文和一个背景上下文。所有新的子上下文都是背景上下文的子上下文。
当我在 6 的后台线程中更新子上下文中的项目时,它们永远不会合并到主上下文,直到我重新启动应用程序并且主上下文从商店中获取它们。但是,在 ios7 上,这一切都很好。如何确保主上下文正确刷新合并而不会出错并重新加载数据库?
我知道 iOS 7 默认打开异步 sql 访问,但我已经在 6 上做到了:
NSSQLitePragmasOption : @{@"journal_mode" : @"WAL"}
这是我的上下文的设置方式:
self.mainManagedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
[self.mainManagedObjectContext setPersistentStoreCoordinator:self.mainPersistentStoreCoordinator];
[self.mainManagedObjectContext setMergePolicy:NSMergeByPropertyStoreTrumpMergePolicy];
[self.mainManagedObjectContext setUndoManager:nil];
self.backgroundParentContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
[self.backgroundParentContext setPersistentStoreCoordinator:self.backgroundPersistentStoreCoordinator];
[self.backgroundParentContext setMergePolicy:NSMergeByPropertyStoreTrumpMergePolicy];
[self.backgroundParentContext setUndoManager:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(backgroundContextDidSave:) name:NSManagedObjectContextDidSaveNotification object:self.backgroundParentContext];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(mainContextDidSave:) name:NSManagedObjectContextDidSaveNotification object:self.mainManagedObjectContext];
这是我创建子上下文的方法:
- (NSManagedObjectContext *)newChildManagedObjectContext
{
NSManagedObjectContext *childContext = [[NSManagedObjectContext alloc]
initWithConcurrencyType:NSPrivateQueueConcurrencyType];
[childContext setMergePolicy:NSMergeByPropertyObjectTrumpMergePolicy];
[childContext setParentContext:self.backgroundParentContext];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(managedObjectContextDidSave:)
name:NSManagedObjectContextDidSaveNotification object:childContext];
[childContext setUndoManager:nil];
return childContext;
}
以下是通知方法:
- (void)mainContextDidSave:(NSNotification *)notification
{
__block NSNotification *strongNotification = notification;
[self.backgroundParentContext performBlockAndWait:^{
[self.backgroundParentContext mergeChangesFromContextDidSaveNotification:strongNotification];
}];
}
- (void)backgroundContextDidSave:(NSNotification *)notification
{
[self.mainManagedObjectContext performSelectorOnMainThread:@selector(mergeChangesFromContextDidSaveNotification:) withObject:notification waitUntilDone:NO];
}
- (void)managedObjectContextDidSave:(NSNotification *)notification
{
[self.backgroundParentContext performBlockAndWait:^{
NSError *error = nil;
if (![self.backgroundParentContext save:&error]) {
DNSLog(@"error saving context: %@", error);
}
}];
}
更新:
好吧,这似乎永远不会在 6 上工作。根据文档,他们在合并 7 的上下文方面发生了很大变化。所以我将不得不对 6 采取不同的方法,我猜......