final class TestVC: UIViewController {
var usersFooter: Footer!
var groupsFooter: Footer!
override func viewDidLoad() {
super.viewDidLoad()
bind(footer: &usersFooter)
}
func bind(footer: inout Footer) {
footer = Footer(style: .autoFooter, height: 57) {
// doing something
}
}
}
Thats what Footer is:
final class Footer: RefreshView {
private var loader: MDCActivityIndicator!
override public init(style: Style, height: CGFloat, action: @escaping () -> Void) {
// initializing and doing something with loader
super.init(style: style, height: height, action: action)
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
}
I get this:
Cannot pass immutable value of type 'Footer' as inout argument
How to pass TestVC instance's footers in it's function and be able to initialize them? Why is footer that immutable (Declared as var)?
This occurs because
var someVar: Footer!
does not define a variable of type Footer
but a variable of type Optional<Footer>
that is implicitly unwrapped. The code:
var someFooter: Footer!
bind(footer: &someFooter)
is logically equivalent to
var someFooter: Footer?
guard let tempFooter = someFooter? else { fatalError() }
bind(footer: &tempFooter)
As you can see, tempFooter
is a let, so it can't be passed as an inout variable and even if it could, the result would be thrown away.
You can fix this in one of three ways:
make the parameter to bind an optional, e.g. func bind(footer: inout Footer?)
or use Martin's syntax to make it implicitly optional.
Force the unwrap yourself:
var unwrapped: Footer = someFooter
bind(footer: unwrapped)
someFooter = unwrapped
redesign the API. It seems the first thing you do in the bind
function is overwrite the old footer with a newly initialised footer. So don't use an inout parameter, return the value you want i.e.
func bind() -> Footer
{
var theFooter = Footer(...) { ... }
// do stuff
return theFooter
}
someFooter = bind()
I think the last option is the best in this case.