I have created a very simple example of how a UIViewController represented by UIViewControllerRepresentable is never deallocated.
struct ContentView : View {
@State private var showRepView = true
var body: some View {
VStack {
Text("Square").font(.largeTitle).tapAction {
self.showRepView.toggle()
}
if showRepView {
SomeRepView().frame(width: 100, height: 200)
}
}
}
}
The representation implementation follows:
struct SomeRepView: View {
var body: some View {
RepViewController()
}
}
struct RepViewController: UIViewControllerRepresentable
{
func makeUIViewController(context: Context) -> SomeCustomeUIViewController {
let vc = SomeCustomeUIViewController()
print("INIT \(vc)")
return vc
}
func updateUIViewController(_ uiViewController: SomeCustomeUIViewController, context: Context) {
}
static func dismantleUIViewController(_ uiViewController: SomeCustomeUIViewController, coordinator: Self.Coordinator) {
print("DISMANTLE")
}
}
class SomeCustomeUIViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = UIColor.green
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
print("viewWillDissapear \(self)")
}
deinit {
print("DEINIT \(self)")
}
}
By tapping on the "Square" button,
SomeRepView
is added and removed alternatively. However, the related UIViewController is never released.That can be seen by the logged messages and I also confirmed with Instruments.
Note that SomeRepView is released properly. It is only the corresponding view controller what remains allocated.
Also note that the
UIViewController.viewWillDissappear
is called and also the UIViewControllerRepresentable.dismantleUIViewController
This is a typical output when pressing the Square button repeatedly.
INIT <SomeCustomeUIViewController: 0x100b1af70>
DISMANTLE
viewWillDissapear <SomeCustomeUIViewController: 0x100b1af70>
INIT <SomeCustomeUIViewController: 0x100a0a8c0>
DISMANTLE
viewWillDissapear <SomeCustomeUIViewController: 0x100a0a8c0>
INIT <SomeCustomeUIViewController: 0x100b23690>
DISMANTLE
viewWillDissapear <SomeCustomeUIViewController: 0x100b23690>
As shown,
DEINIT
is never printed.Running with iOS13, beta 2, iPad 6th Gen and on the simulator. I also tried triggered a Simulate Memory Warning. But no effect. The controllers persist in memory.
My question is... is it a bug? Or am I doing something wrong?