Parent_Context
Child_context(将Parent_Context设置为父级)
在后台使用的Child_context,用于添加新数据或更新现有数据。 Parent_Context在UI上显示并保存数据持久存储。
Child_context保存不应花费时间,因为更改仅在内存中更新。这更新为Parent_Context。
在写入商店时,Parent_Context保存可能需要一些时间。因此,我们可以根据应用程序的需要选择何时保存Parent_Context。
这就是我在多线程环境中需要时通常使用上下文的方法,或者在仍然在后台访问数据时更新UI。
// Parent or main
_mainQueueContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
_mainQueueContext.persistentStoreCoordinator = self.persistentStoreCoordinator;
// Child or background context
_privateQueueContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
[_privateQueueContext setParentContext:self.mainQueueContext]; // Set main threads MOC as parent.
//To Save
if ([self privateQueueContext].hasChanges) {
[[self privateQueueContext] performBlockAndWait:^{
NSError *childError = nil;
if ([[self privateQueueContext] save:&childError]) {
[[self mainQueueContext] performBlock:^{
NSError *parentError = nil;
if (![[self mainQueueContext] save:&parentError]) {
DLog(@"Error saving parent, error: %@", [parentError localizedDescription]);
}
}];
} else {
DLog(@"Error saving child, error: %@", [childError localizedDescription]);
}
}];
}
如果有更好的方法来处理这种情况,请分享。感谢。
通过在后台线程中保存上下文,我看不到UI被冻结。发布问题以了解其他更好的方法并了解核心数据。
答案 0 :(得分:3)
我更喜欢至少有2个上下文。
与持久性存储相关联的主要内容(没有父上下文)为privateQueueConcurrencyType
,因此在保存到磁盘期间不会影响UI。
第二个是用于UI的viewContext,它是privateContext的子上下文。
我通常还有另一个用于后台导入的导入,它是UI上下文的子上下文,并配置为privateQueueConcurrencyType
,因此它不会阻止UI。保存后,UI会更新,然后更改将保存到持久性存储中(以递归方式保存)。
此外,每当我要进行更改时,我都会为viewContext创建一次性子上下文。我在childContext中进行更改,然后以递归方式保存。我发现这种方式可以在多用户情况下多次保存我的屁股。
以下是我的设置:
lazy var privateSaveContext: NSManagedObjectContext = {
let moc = NSManagedObjectContext(concurrencyType: .privateQueueConcurrencyType)
moc.name = "privateSaveContext"
moc.persistentStoreCoordinator = self.coordinator
moc.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy
return moc
}()
lazy var viewContext: NSManagedObjectContext = {
let moc = NSManagedObjectContext(concurrencyType: .mainQueueConcurrencyType)
moc.name = "viewContext"
moc.parent = self.privateSaveContext
moc.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy
return moc
}()
lazy var importContext: NSManagedObjectContext = {
let moc = NSManagedObjectContext(concurrencyType: .privateQueueConcurrencyType)
moc.name = "importContext"
moc.parent = self.viewContext
moc.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy
return moc
}()
保存到磁盘时,我以递归方式保存:
class func save(_ moc: NSManagedObjectContext) {
moc.performAndWait {
if moc.hasChanges {
DLog("Inserted objects count = \(moc.insertedObjects.count)")
do {
try moc.save()
if moc.parent == nil { DLog("SAVED changes to persistent store") }
DLog("SAVED context '\(moc)'")
} catch {
DLog("ERROR saving context '\(moc)' - \(error)")
}
} else {
if moc.parent == nil { DLog("SKIPPED saving changes to persistent store, because there are no changes") }
DLog("SKIPPED saving context '\(moc)' because there are no changes")
}
if let parentContext = moc.parent {
save(parentContext)
}
}
}
P.S。 DLog
是我使用的,它打印出函数名称,日期,时间等。您只需将其更改为print
。