这里是核心数据新手。我正在尝试更改 NSPersistentDocument
的默认 NSManagedObjectContext
,以便初始化它并将其与 NSMainQueueConcurrencyType
一起使用。
目前我正在 -windowControllerDidLoadNib:
中执行此操作,如下所示:
- (void)windowControllerDidLoadNib:(NSWindowController *)aController
{
[super windowControllerDidLoadNib:aController];
NSManagedObjectContext *newMOC = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
[newMOC setPersistentStoreCoordinator:[self.managedObjectContext persistentStoreCoordinator]];
[self setManagedObjectContext:newMOC];
}
这看起来效果很好。但我想知道在 -windowControllerDidLoadNib:
中初始化 MOC 是否是最好的做法,或者是否应该将其放置在其他地方和/或以不同的方式初始化。
感谢您的帮助。
最佳答案
我正在试验基于文档的 CoreData 应用程序的 Xcode 模板。该模板创建一个 init()
覆盖,它只调用 super.init()
。我想在后台运行大型导入,因此我将其添加到文档类中:
class Document: NSPersistentDocument {
private var importQueue = DispatchQueue(label: "Importer")
override init() {
super.init()
let moc = NSManagedObjectContext(concurrencyType: .mainQueueConcurrencyType)
moc.mergePolicy = self.managedObjectContext!.mergePolicy
moc.persistentStoreCoordinator = self.managedObjectContext!.persistentStoreCoordinator
self.managedObjectContext = moc
}
func importStuff(url: URL) {
let moc = NSManagedObjectContext(concurrencyType: .privateQueueConcurrencyType)
moc.parent = self.managedObjectContext
var count = 0
moc.performAndWait {
...
count += 1
if count % 10000 == 0 {
do {
try moc.save()
moc.reset()
}
catch {
Swift.print("save failed at record #\(count): \(error.localizedDescription)")
}
}
return true
}
do {
try moc.save()
}
catch {
Swift.print("save failed at records #\(count): \(error.localizedDescription)")
}
}
Swift.print("imported \(count) records.")
}
@IBAction func import(_ sender: Any) {
...
importQueue.async {
self.importStuff(url: url)
}
}
}
这在我的初始测试中似乎工作正常。我认为在 -windowControllerDidLoadNib:
中初始化一个新的 MOC 是可以的,但是如果您将对象 Controller 绑定(bind)到文档 MOC,它们可能会在 MOC 更改时执行第二次获取。在 init
中初始化它会在 UI 加载之前更快地初始化它。
关于cocoa - 更改 NSPersistentDocument 的默认 NSManagedObjectContext,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22590885/