【问题标题】:SwiftUI memory leak when using UIViewControllerRepresentable使用 UIViewControllerRepresentable 时 SwiftUI 内存泄漏
【发布时间】:2025-08-05 16:10:01
【问题描述】:

更新:从 beta4 开始,问题仍然存在。

我创建了一个非常简单的示例,说明由 UIViewControllerRepresentable 表示的 UIViewController 如何从不被释放。

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

    }
}

表示实现如下:

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)")
    }

}

通过点击“方形”按钮,SomeRepView 会交替添加和删除。但是,相关的 UIViewController 永远不会发布。这可以从记录的消息中看到,我也通过 Instruments 确认了这一点。

请注意 SomeRepView 已正确释放。只有相应的视图控制器仍然被分配。

还要注意UIViewController.viewWillDissappearUIViewControllerRepresentable.dismantleUIViewController 被调用

这是重复按方形按钮的典型输出。

INIT <SomeCustomeUIViewController: 0x100b1af70>
DISMANTLE
viewWillDissapear <SomeCustomeUIViewController: 0x100b1af70>
INIT <SomeCustomeUIViewController: 0x100a0a8c0>
DISMANTLE
viewWillDissapear <SomeCustomeUIViewController: 0x100a0a8c0>
INIT <SomeCustomeUIViewController: 0x100b23690>
DISMANTLE
viewWillDissapear <SomeCustomeUIViewController: 0x100b23690>

如图所示,DEINIT 永远不会被打印出来。

我的问题是……这是一个错误吗?还是我做错了什么?

运行 iOS13,beta 4。

我尝试触发模拟内存警告。没有效果。控制器持续存在。 Instruments 是我的见证人 ;-)

【问题讨论】:

    标签: swiftui


    【解决方案1】:

    在 Xcode 11,beta 5 中,已修复错误。

    【讨论】:

    • 很抱歉,这仍然保留在 Xcode 12.5 中
    • 发生在 Xcode 13 中