[英]Is it ok to call closures in UIKit UIViewController from Hosted SwiftUI View?
I'm hosting ContentView
in WrapperViewController
like this:我在
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?()
}
}
}
I'm calling buttonTapped
in the WrapperViewController
from ContentView
, but is this fine?我正在从
ContentView
调用buttonTapped
中的WrapperViewController
,但这可以吗? "tapped button" is getting printed, but I read this article that said “点击按钮”正在打印,但我读了这篇文章说
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. }
So should I use a closure here?那么我应该在这里使用闭包吗? Or am I supposed to do something else?
还是我应该做点别的?
We cannot use [weak myCar] as myCar is a value type.
我们不能使用 [weak myCar],因为 myCar 是一个值类型。
In the example from the article, myCar
is a struct .在文章的示例中,
myCar
是一个struct 。
However, in your code:但是,在您的代码中:
contentView.buttonTapped = { [weak self] in
self?.tappedButton()
}
self
is a UIViewController
which is a class (and a reference type). self
是一个UIViewController
,它是一个类(和一个引用类型)。
Your use of [weak self]
is perfectly fine: the closure will keep a weak reference to the UIViewController and when you tap a button, the tappedButton()
function will be called.您对
[weak self]
的使用非常好:闭包将保持对 UIViewController 的弱引用,当您点击按钮时,将tappedButton()
函数。 Which is probably what you expect.这可能是您所期望的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.