I can't figure out why a UIViewController instantiated with UIStoryboard.instantiateViewController does not deinit when initalized in a unit test
Here's the code that I expect to deinit but does not:
func testDoesNotDeinit() throws {
var strongViewController: ViewController? =
UIStoryboard(
name: "Main",
bundle: Bundle(for: ViewController.self)
)
.instantiateViewController(withIdentifier: "ViewController") as! ViewController
print("set nil")
strongViewController = nil
print("post set nil")
}
The result is:
set nil
post set nil
*** deinit *** // From deinit {} function in UIViewController
When the UIViewController is initialized programmatically it will deinitialize properly
func testDoesDeinit() throws {
var strongViewController: ViewController? = ViewController()
XCTAssertNotNil(strongViewController)
print("set nil")
strongViewController = nil
print("post set nil")
XCTAssertNil(strongViewController)
}
with result:
set nil
*** deinit *** // From deinit {} function in UIViewController
post set nil
Any ideas?
I set a breakpoint at
print("post set nil")
and inspected the memory graph at that point in time. I saw that the VC is being retained by an instance ofUIStoryboardScene
:UIStoryboardScene
seems to be a private API. The only thing I can find about it is this header. This is probably an implementation detail ofinstantiateViewController
.