cocoa - 更改 NSPersistentDocument 的默认 NSManagedObjectContext

标签 cocoa core-data nsmanagedobjectcontext nspersistentdocument

这里是核心数据新手。我正在尝试更改 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/

相关文章:

objective-c - objective-c - 核心数据保存方法

objective-c - 用于 Cocoa OS x 的语音到文本转录 API

macos - NSView的wantLayer表现

arrays - 如何将数组元素按顺序保存到Core Data中

cocoa - 在GC环境下,Core Data什么时候会释放分配的内存?

objective-c - 当删除前一个元素时,如何设置与其他元素的一对一关系?

ios - 保存 ManagedObjectContext 时处理错误

Objective-C OS X 系统命令

objective-c - 无法拖放到 NSCollectionView 上

objective-c - 更改托管对象属性不会触发 NSFetchedResultsController 更新 TableView