13

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 ;-)

1 Answer 1

6

In Xcode 11, beta 5, bug was patched.

Sign up to request clarification or add additional context in comments.

2 Comments

Sorry to say but this still remains in Xcode 12.5
Happening for us in Xcode 13

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.