使用 UIViewControllerRepresentable 时的 SwiftUI 内存泄漏 [英] SwiftUI memory leak when using UIViewControllerRepresentable

查看:49
本文介绍了使用 UIViewControllerRepresentable 时的 SwiftUI 内存泄漏的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

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

    }
}

表示实现如下:

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

}

通过点击Square"按钮,SomeRepView 被交替添加和删除.但是,相关的 UIViewController 永远不会发布.这可以从记录的消息中看出,我也通过 Instruments 进行了确认.

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.

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

Note that SomeRepView is released properly. It is only the corresponding view controller what remains allocated.

还要注意 UIViewController.viewWillDissappear 被调用,还有 UIViewControllerRepresentable.dismantleUIViewController

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>

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

As show, DEINIT is never printed.

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

My question is... is it a bug? Or am I doing something wrong?

运行 iOS13,测试版 4.

Running with iOS13, beta 4.

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

I tried triggering Simulate Memory Warning. No effect. The controllers persist. Instruments is my witness ;-)

推荐答案

在 Xcode 11、beta 5 中,已修补错误.

In Xcode 11, beta 5, bug was patched.

这篇关于使用 UIViewControllerRepresentable 时的 SwiftUI 内存泄漏的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆