Last active
October 16, 2019 13:04
-
-
Save devxoul/a376db02653ccff732d365636d486f03 to your computer and use it in GitHub Desktop.
Does UIViewController get deallocated synchronously? NO. (if view is loaded)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
weak var weakViewController: UIViewController? | |
_ = { | |
let viewController = UIViewController() | |
viewController.loadViewIfNeeded() // this line prevents from deallocation | |
weakViewController = viewController | |
}() | |
XCTAssertNil(weakViewController) // (fail) weakViewController = Optional(<UIViewController: 0x7fd55e705080>) | |
DispatchQueue.main.async { | |
print(weakViewController) // nil | |
} |
심플하게 테스트 해보려면 loadView...를 사용할 필요없이 performSelector를 통해 직접 _nonModalAncestorViewControllerStopAtIsPresentationContext: 를 호출하면 되는데, swift에서는 perform selector를 사용하는 과정에서 autorelease풀에 등록이 되어버리니 테스트 케이스를 objective c로 생성하고 나서야 명확하게 이유를 살펴볼 수 있었습니다.
arc 에서의 autorelease 최적화와 관련한 이슈라고 생각합니다. 같은 문제를 일으키는 좀 더 간단한 구현체를 만들어보는 중이네요. (아니면 -fno-objc-arc 플래그로 컴파일을 해봐야하나 .. 고민)
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
UIViewController.loadViewIfNeeded() -> .loadViewIfRequired() -> .loadView() -> .defaultInitialViewFrame() -> ._window -> ._rootAncestorViewController -> .nonModalAncestorViewControllerStopAtIsPresentationContext( flag: Bool) -> Self(UIViewController) 로 진행하면서 마지막 _nonModal...에서 자기자신(UIViewController)를 반환하며 현재의 오토릴리즈 풀에 등록시키는 것이 원인이었네요.
결국 SwiftUI방에서 원숭이님이 autorelease풀을 별도로 사용하신게 정답이었군요.