Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/cocoa/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Cocoa 更改NSPersistentDocument的默认NSManagedObjectContext_Cocoa_Core Data_Nsmanagedobjectcontext_Nspersistentdocument - Fatal编程技术网

Cocoa 更改NSPersistentDocument的默认NSManagedObjectContext

Cocoa 更改NSPersistentDocument的默认NSManagedObjectContext,cocoa,core-data,nsmanagedobjectcontext,nspersistentdocument,Cocoa,Core Data,Nsmanagedobjectcontext,Nspersistentdocument,核心数据新手在这里。我正在尝试更改NSPersistentDocument的默认NSManagedObjectContext,以便将其初始化并与NSMainQueueConcurrencyType一起使用 目前我在-windowcontrolleridloadnib:中这样做: - (void)windowControllerDidLoadNib:(NSWindowController *)aController { [super windowControllerDidLoadNib:a

核心数据新手在这里。我正在尝试更改
NSPersistentDocument
的默认
NSManagedObjectContext
,以便将其初始化并与
NSMainQueueConcurrencyType
一起使用

目前我在
-windowcontrolleridloadnib:
中这样做:

- (void)windowControllerDidLoadNib:(NSWindowController *)aController
{
    [super windowControllerDidLoadNib:aController];
    NSManagedObjectContext *newMOC = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
    [newMOC setPersistentStoreCoordinator:[self.managedObjectContext persistentStoreCoordinator]];
    [self setManagedObjectContext:newMOC];
}
这似乎效果不错。但我想知道在
-windowcontrolleridloadnib:
中初始化MOC是否是最好的方法,或者是否应该将其放置在其他位置和/或以不同的方式初始化


感谢您的帮助。

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

我正在试验基于文档的CoreData应用程序的Xcode模板。模板创建了一个
init()
覆盖,它只调用
super.init()
。我想在后台运行大型导入,因此我将其添加到document类中:

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)
        }
    }
}

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

但有时您可能需要一个子MOC以方便还原。在这种情况下,“传递指挥棒”的方法将不起作用。经过测试,它起作用了。我认为这应该是公认的答案。