3

核心数据新手在这里。我正在尝试更改 , 的默认值NSManagedObjectContextNSPersistentDocument以便对其进行初始化并将其与NSMainQueueConcurrencyType.

目前我正在这样做-windowControllerDidLoadNib:

- (void)windowControllerDidLoadNib:(NSWindowController *)aController
{
    [super windowControllerDidLoadNib:aController];
    NSManagedObjectContext *newMOC = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
    [newMOC setPersistentStoreCoordinator:[self.managedObjectContext persistentStoreCoordinator]];
    [self setManagedObjectContext:newMOC];
}

这似乎工作正常。但我想知道 MOC 的初始化-windowControllerDidLoadNib:是否是最好的做法,或者它是否应该放在其他地方和/或以不同的方式初始化。

谢谢你的帮助。

4

2 回答 2

2

我正在试验基于文档的 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)
        }
    }
}

在我的初始测试中,这似乎工作正常。我认为在其中初始化一个新的 MOC-windowControllerDidLoadNib:是可以的,但是如果您将对象控制器绑定到文档 MOC,它们可能会在 MOC 更改时执行第二次获取。在init加载 UI 之前,在 中初始化它会更快地初始化它。

于 2017-03-18T16:41:05.753 回答
0

首选模式是“传递接力棒”方法,您将托管对象上下文传递给子视图控制器。给你的控制器一个托管对象上下文属性,并在你展示它们时简单地传递它。

于 2014-03-23T22:37:22.157 回答