我有一个基于 NSDocument
且带有 Core Data 的 macOS 应用程序,其本质上一次只能打开一个文档。因此,当打开一个新文档时,我会关闭当前打开的文档。
所有与文档相关的 UI 都位于单独的窗口 Controller 中,一切正常。
但我还有一个菜单栏项目,可以切换一个单独的窗口,其中显示有关文档的一些信息。 UI 是一个绑定(bind)到 NSArrayController
的简单 NSTableView
。当当前文档更改时,会设置数组 Controller 的 managgedObjectContext
属性。这总是会导致 EXC_BAD_INSTRUCTION
崩溃。
为了缩小问题范围,我完全删除了阵列 Controller 的所有绑定(bind)和任何其他操作。崩溃消失了。
我还在代码中创建了一个新的 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()
会以某种方式将数组 Controller 锁定到特定的 ManagedObjectContext,并在将其设置为 nil 时导致崩溃。
如何安全地“停用”NSArrayController
,或更改其 ManagedObjectContext?
最佳答案
经过大量实验,我想我发现只要您调用 fetch(_:)
或 preopareContent()<,
。看起来它保留了它的NSArrayController
就会产生内存泄漏managedObjectContext
并且永远不会释放它。即使对 Controller 的所有其他引用都已被释放,我仍然可以在内存调试器中看到泄漏的实例。
我通过用常规的 NSTableViewDataSource
实现替换绑定(bind)来解决这个问题。
关于macos - 将 NSArrayController 的 ManagedObjectContext 设置为 nil 时崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61426112/