Вы пытаетесь инициализировать переменную модели представления и передать контроллер представления в качестве делегата, который на данный момент не полностью инициализирован.
Попробуйте проверить очень информативное и очень подробное Инициализация *Страница 1004 * в официальном руководстве по языку Swift.
Поскольку этот протокол используется для этой конкретной цели, мы можем смело ограничить его классами (обратите внимание на добавление : class
к вашему коду.
protocol SecondViewModelEvents: class {
func changeBackground()
}
Хорошей практикой является использование более описательного именования, а также использование слабых ссылок для объектов делегатов во избежание циклов сильных ссылок.
class SecondViewModel {
weak var delegate: SecondViewModelEvents?
init(delegate: SecondViewModelEvents) {
self.delegate = delegate
}
func loadDataFromServer() {
delegate?.changeBackground()
}
}
Вы можете попробовать использовать дополнительную модель представления, которая будетполучить инициализацию в соответствующем месте, например awakeFromNib()
:
class SecondViewController: UIViewController, SecondViewModelEvents {
var viewModel: SecondViewModel?
override func awakeFromNib() {
super.awakeFromNib()
viewModel = SecondViewModel(delegate: self)
}
@IBAction func buttonPressed(_ sender: Any) {
viewModel?.loadDataFromServer()
}
func changeBackground() {
view.backgroundColor = UIColor.red
}
}
Или альтернативный подход может состоять в инициализации не необязательной модели представления в UIViewController
необходимом инициализаторе:
// ...
var viewModel: SecondViewModel
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
self.viewModel = SecondViewModel(delegate: self)
}
// ...