I am building a macOS Document based application. I am following Apple's example code, which can be found here.
In Apple's example, the NSDocument assigns itself as the NSViewController's representedObject. The NSDocument also retains a strong reference to the NSViewController. As far as I can see, this should cause a retain cycle, which indeed happens in my implementation of the code. But in Apple's example, it does not cause a retain cycle, and I can't work out why. Here is Apple's example code:
class Document: NSDocument {
var contentViewController: ViewController!
override func makeWindowControllers() {
// Returns the storyboard that contains your document window.
let storyboard = NSStoryboard(name: NSStoryboard.Name("Main"), bundle: nil)
if let windowController =
storyboard.instantiateController(
withIdentifier: NSStoryboard.SceneIdentifier("Document Window Controller")) as? NSWindowController {
addWindowController(windowController)
// Set the view controller's represented object as your document.
if let contentVC = windowController.contentViewController as? ViewController {
contentVC.representedObject = content
contentViewController = contentVC
}
}
}
}
The only difference in my implementation is that my ViewController is further down the hierarchy, as it is contained within an NSSplitViewController, so my NSDocument subclass finds it like so:
override func makeWindowControllers() {
// Returns the Storyboard that contains your Document window.
let storyboard = NSStoryboard(name: NSStoryboard.Name("Main"), bundle: nil)
let windowController = storyboard.instantiateController(withIdentifier: NSStoryboard.SceneIdentifier("Document Window Controller")) as! MainWindowWC
addWindowController(windowController)
if let splitVC = windowController.contentViewController as? NSSplitViewController {
for item in splitVC.splitViewItems {
if let vc = item.viewController as? ViewController {
vc.representedObject = self
contentViewController = vc
}
}
}
}
I can't see that this is causing the problem, and indeed when I close the window, the NSWindowController and NSSplitViewController both successfully deinitialise, but the NSViewController and NSDocument are retained.
I can solve the retain cycle by creating a weak reference to the NSDocument in the NSViewController, instead of using the .representedObject property. but it would be great to know why Apple's code is not causing the retain cycle I think it should.
Thanks,
Dan