将NSArrayController的managedObjectContext设置为nil时崩溃

问题描述 投票:0回答:1

我有一个带有Core Data的基于NSDocument的macOS应用,其本质上一次只能打开一个文档。因此,当打开一个新文档时,我将关闭当前打开的文档。所有与文档相关的UI都位于单独的窗口控制器中,并且一切正常。

但是我还有一个菜单栏项目,可切换一个单独的窗口,该窗口显示有关文档的一些信息。 UI是绑定到NSTableView的简单NSArrayController。当前文档更改时,将设置阵列控制器的managagedObjectContext属性。这总是会导致EXC_BAD_INSTRUCTION崩溃。

为了缩小问题的范围,我完全删除了所有绑定以及对数组控制器的任何其他操作。崩溃不见了。我还用代码创建了一个新的testArrayController,以查看在那里发生了什么,并确定我可以重现崩溃:

let testArrayController = NSArrayController()

var document: Document? {
    didSet {
        if document != nil {
            testArrayController.managedObjectContext = document?.managedObjectContext
            testArrayController.prepareContent()  // <---- this causes the crash later on
        } else {
            testArrayController.managedObjectContext = nil
        }
    }
}

override func viewDidLoad() {
    super.viewDidLoad()

    testArrayController.entityName = "MyEntity"
    ...
}

似乎调用prepareContent()会以某种方式将数组控制器锁定到特定的ManagedObjectContext,并在将其设置为nil时导致崩溃。

如何安全地“停用” NSArrayController或更改其managedObjectContext?

macos cocoa core-data appkit nsarraycontroller
1个回答
0
投票

[经过大量的实验,我想我发现,只要您调用NSArrayControllerfetch(_:)preopareContent()就会产生内存泄漏。似乎它保留了它的managedObjectContext而从不释放它。即使已经释放了对控制器的所有其他引用,我仍可以在内存调试器中看到泄漏的实例。

我通过用常规的NSTableViewDataSource实现替换绑定来解决此问题。

© www.soinside.com 2019 - 2024. All rights reserved.