【问题标题】:Crash when setting NSArrayController's managedObjectContext to nil将 NSArrayController 的 managedObjectContext 设置为 nil 时崩溃
【发布时间】:2020-08-09 01:46:19
【问题描述】:

我有一个基于 NSDocument 的带有 Core Data 的 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】:

经过大量实验,我想我发现NSArrayController 在您调用fetch(_:)preopareContent() 时会产生内存泄漏。它似乎保留了它的managedObjectContext 并且永远不会释放它。即使对控制器的所有其他引用都已释放,我仍可以在内存调试器中看到泄漏的实例。

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-13
    • 1970-01-01
    • 2020-01-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多