Инициализируйте переменные экземпляра внутри функции экземпляра
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
}
}
}
Вот что такое Footer:
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)
}
}
Я получаю это:
Невозможно передать неизменяемое значение типа "Нижний колонтитул" в качестве аргумента inout
Как передать нижние колонтитулы экземпляра TestVC в его функцию и иметь возможность их инициализировать? Почему нижний колонтитул является неизменным (объявлен как var)?
2 ответа
Это происходит потому, что
var someVar: Footer!
не определяет переменную типа Footer
но переменная типа Optional<Footer>
это неявно развернуто. Код:
var someFooter: Footer!
bind(footer: &someFooter)
логически эквивалентно
var someFooter: Footer?
guard let tempFooter = someFooter? else { fatalError() }
bind(footer: &tempFooter)
Как вы видете, tempFooter
это let, поэтому он не может быть передан как переменная inout, и даже если бы он мог, результат был бы отброшен.
Вы можете исправить это одним из трех способов:
сделать параметр для привязки необязательным, например
func bind(footer: inout Footer?)
или используйте синтаксис Мартина, чтобы сделать его неявным образом необязательным.Вынуди себя развернуть:
var unwrapped: Footer = someFooter bind(footer: unwrapped) someFooter = unwrapped
перепроектировать API. Кажется, первое, что вы делаете в
bind
Функция перезаписывает старый нижний колонтитул новым инициализированным нижним колонтитулом. Так что не используйте параметр inout, верните желаемое значение, т.е.func bind() -> Footer { var theFooter = Footer(...) { ... } // do stuff return theFooter } someFooter = bind()
Я думаю, что последний вариант является лучшим в этом случае.
Написать bind
метод, как это. Это разрешит вашу ошибку.
func bind(footer: inout Footer!) {
footer = Footer(style: .autoFooter, height: 57) {
// doing something
}
}
Кажется, что inout думает Footer & Footer! разные. Либо обновите метод, как указано выше, либо измените объявление, как указано ниже.
var userFooter: Footer
Я не знаю точной причины, но ошибка, которую мы получаем, сбивает с толку.