可以从 Hosted SwiftUI View 调用 UIKit UIViewController 中的闭包吗?

Is it ok to call closures in UIKit UIViewController from Hosted SwiftUI View?

我在 WrapperViewController 中托管 ContentView 是这样的:

class WrapperViewController: UIViewController {
    
    init() {
        super.init(nibName: nil, bundle: nil)
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    override func loadView() {
        
        self.view = UIView()

        var contentView = ContentView()
        contentView.buttonTapped = { [weak self] in
            self?.tappedButton()
        }
        
        let contentViewController = UIHostingController(rootView: contentView)
        
        self.addChild(contentViewController)
        self.view.addSubview(contentViewController.view)

        contentViewController.view.frame = view.bounds
        contentViewController.view.autoresizingMask = [.flexibleWidth, .flexibleHeight]
        contentViewController.didMove(toParent: self)
    }
    
    func tappedButton() {
        print("tapped button")
    }
}

struct ContentView: View {
    var buttonTapped: (() -> Void)?
    
    var body: some View {
        Button("Tap me") {
            buttonTapped?()
        }
    }
}

我正在从 ContentView 呼叫 WrapperViewController 中的 buttonTapped,但这可以吗? “点击按钮”正在打印,但我读到这个 ​​article

When you use closures in structs, the closure behaves as a reference type, and the problem starts there. The closures need to have a reference to the environment outside so that the environment can be modified when the closure body is executed.

struct Car {
   var speed: Float = 0.0
   var increaseSpeed: (() -> ())?
}
var myCar = Car()
myCar.increaseSpeed = {
    myCar.speed += 30 // The retain cycle occurs here. We cannot use [weak myCar] as myCar is a value type.
}

那么我应该在这里使用闭包吗?还是我应该做点别的?

We cannot use [weak myCar] as myCar is a value type.

在文章的示例中,myCar 是一个 struct

但是,在您的代码中:

contentView.buttonTapped = { [weak self] in
    self?.tappedButton()
}

self 是一个 UIViewController,它是一个 class(和引用类型)。

您对 [weak self] 的使用完全没问题:闭包将保持对 UIViewController 的弱引用,当您点击按钮时,将调用 tappedButton() 函数。这可能是您所期望的。