在结构体中,传入的委托属性是否也应该声明为弱引用(weak)?
在结构体中,传入的委托属性是否也应该声明为弱引用(weak)?
根据Swift书籍的说法,为了防止强引用循环,代理被声明为弱引用。
protocol SomeDelegate: AnyObject {
}
class viewController: UIViewController, SomeDelegate {
weak var delegate: SomeDelegate?
override func viewDidLoad() {
delegate = self
}
}
假设该类使用该代理参数化了一个结构体。
class viewController: UIViewController, SomeDelegate {
weak var delegate: SomeDelegate?
override func viewDidLoad() {
delegate = self
let exampleView = ExampleView(delegate: delegate)
let hostingController = UIHostingController(rootView: exampleView)
self.present(hostingController, animated: true)
}
}
struct ExampleView: View {
weak var delegate: SomeDelegate!
var body: some View {
Text("")
}
}
那么在结构体中的代理属性是否也应该标记为 `weak`?
原因:在这个问题中,我们希望拥有委托的对象使用一个弱引用来引用其委托,即在这种情况下是ExampleView。在视图控制器中声明对委托的引用实际上在这里并没有任何用处,除非你计划在viewDidLoad()块之外使用它。但是无论如何,你已经可以这样做,因为你可以随时引用self。
解决方法:书中建议在这里使用一个弱引用self,因为一旦self不存在,就不希望保留任何内容;通过将其设置为弱引用,一旦不再需要委托,它就会被销毁。
class viewController: UIViewController, SomeDelegate {
override func viewDidLoad() {
let exampleView = ExampleView(delegate: self)
// ^ 注意这里是self,而不是delegate
let hostingController = UIHostingController(rootView: exampleView)
self.present(hostingController, animated: true)
}
}
struct ExampleView: View {
weak var delegate: SomeDelegate?
// ^ 这里是weak,这里是optional ^
var body: some View {
Text("")
}
}
在任何情况下,你几乎没有理由直接从ExampleView中引用委托,因为委托协议方法现在由委托(视图控制器)调用,而不是视图本身。但是如果出于某种原因确实需要这样做,可以检查委托是否已设置,然后引用它,如下所示:
if let delegate = exampleView.delegate {
// do something with delegate
// I'm probably not accounting for optional unwrapping here
}