How to pass a local function to another object during init?
I did the below, but got \'self\' captured by a closure before all members were initialized
First, your property drawViewWrapper
seems to be useless here since you can access it later with self.rootView
and second, you should use [unowned self]
to avoid capturing 'self' and creating a weak reference to it instead (and then avoid a retain-cycle).
So I would do something like this instead:
class ContextViewController: UIHostingController<ContentView> {
init(drawView: CustomDrawView) {
let drawViewWrapper = ContentView(
drawView: drawView,
dismiss: { [unowned self] in
self.dismiss(animated: true)
})
super.init(rootView: drawViewWrapper)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
And then if you need to access it later, you can simply use self.rootView
.
You have to call super.init()
before:
class ContextViewController: UIHostingController<ContentView> {
let drawViewWrapper: ContentView?
init(drawView: CustomDrawView) {
super.init(rootView: self.drawViewWrapper)
self.drawViewWrapper = ContentView(
drawView: drawView,
dismiss: { self.dismiss(animated: true) })
}
}
if it's an option for you I'd suggest making the dismiss
block not part of the init but rather an optional var on the ContentView.
My solution would look kind of like:
ContentView
class ContentView: UIView {
var dismiss: (() -> Void)?
init(drawView: UIView) {
super.init(frame: .zero)
}
...
}
You could also indicate the dismiss block will always be there by replacing the ?
with an !
(var dismiss: (() -> Void)!
) so you don't have to unwrap it when calling but I wouldn't suggest that as it's not compile time safe and so not what you really want.
ContextViewController
class ContextViewController: UIHostingController<ContentView> {
let drawViewWrapper: ContentView
lazy var selfDismiss: () -> Void = { [unowned self] in
self.dismiss(animated: true)
}
init(drawView: CustomDrawView) {
self.drawViewWrapper = ContentView(drawView: drawView)
super.init(rootView: self.drawViewWrapper)
self.drawViewWrapper.dismiss = selfDismiss
}
...
}