将 NSArrayController 的 managedObjectContext 设置为 nil 时崩溃
Crash when setting NSArrayController's managedObjectContext to nil
我有一个基于 NSDocument
的带有 Core Data 的 macOS 应用程序,从本质上讲,它一次只能打开一个文档。因此,当打开一个新文档时,我会关闭当前打开的文档。
所有与文档相关的 UI 都在一个单独的 window 控制器中,并且一切正常。
但我还有一个菜单栏项,它可以切换一个单独的 window,它显示有关文档的一些信息。 UI 是绑定到 NSArrayController
的简单 NSTableView
。数组控制器的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 时导致崩溃。
我怎样才能安全地"deactivate"一个NSArrayController
,或者改变它的managedObjectContext?
经过大量试验后,我想我发现 NSArrayController
在您调用 fetch(_:)
或 preopareContent()
时会产生内存泄漏。它似乎保留了它的 managedObjectContext
并且永远不会释放它。即使所有其他对控制器的引用都已释放,我仍然可以在内存调试器中看到泄漏的实例。
我通过用常规 NSTableViewDataSource
实现替换绑定来解决这个问题。
我有一个基于 NSDocument
的带有 Core Data 的 macOS 应用程序,从本质上讲,它一次只能打开一个文档。因此,当打开一个新文档时,我会关闭当前打开的文档。
所有与文档相关的 UI 都在一个单独的 window 控制器中,并且一切正常。
但我还有一个菜单栏项,它可以切换一个单独的 window,它显示有关文档的一些信息。 UI 是绑定到 NSArrayController
的简单 NSTableView
。数组控制器的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 时导致崩溃。
我怎样才能安全地"deactivate"一个NSArrayController
,或者改变它的managedObjectContext?
经过大量试验后,我想我发现 NSArrayController
在您调用 fetch(_:)
或 preopareContent()
时会产生内存泄漏。它似乎保留了它的 managedObjectContext
并且永远不会释放它。即使所有其他对控制器的引用都已释放,我仍然可以在内存调试器中看到泄漏的实例。
我通过用常规 NSTableViewDataSource
实现替换绑定来解决这个问题。