UPDATE: As of beta4, problem still present.
I have created a very simple example of how a UIViewController represented by UIViewControllerRepresentable is never deallocated.
import SwiftUI
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: 100)
}
}
}
}
The representation implementation follows:
import SwiftUI
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 of 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 show, DEINIT
is never printed.
My question is... is it a bug? Or am I doing something wrong?
Running with iOS13, beta 4.
I tried triggering Simulate Memory Warning. No effect. The controllers persist. Instruments is my witness ;-)
In Xcode 11, beta 5, bug was patched.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With