#ios #swift #viper-architecture
Вопрос:
В проекте, который я сделал с Viper, ведущий в ViewController выдает нулевую ошибку. В чем причина этого? И как я могу решить эту проблему?
AppDelegate
let wireframe = MovieWireframe()
let movies = wireframe.createMovieController()
window = UIWindow(frame: UIScreen.main.bounds)
window?.rootViewController = UINavigationController(rootViewController: movies)
window?.makeKeyAndVisible()
Контроллер просмотра
Ведущий здесь выдает нулевую ошибку.
var presenter: IMoviePresenter? //Nil
override func viewDidLoad() {
super.viewDidLoad()
presenter?.startFetchingMovies() //Nil
}
Ведущий
StartFetchingMovies здесь не работает, потому что ведущий равен нулю.
class MoviePresenter: IMoviePresenter {
var view: IMovieView?
var interactor: IMovieInteractor
var router: IMovieWireframe
var movies: MoviesResult?
init(view: IMovieView?, interactor: IMovieInteractor, router: IMovieWireframe) {
self.view = view
self.interactor = interactor
self.router = router
}
func startFetchingMovies() {
interactor.fetchMovies()
}
func showMovieController(navigationController: UINavigationController) {
router.pushToMovieDetailScreen(navigationController: navigationController)
}
}
extension MoviePresenter: IMovieInteractorDelegate {
func movieInteractorDidSuccessToFetchMovies(movies: MoviesResult) {
self.movies = movies
view?.showMovie(movies: movies)
}
func movieInteractorDidFailToFetchMovies() {
print("error")
}
}
Маршрутизатор
View.presenter здесь не равен нулю.
class MovieWireframe: IMovieWireframe {
func createMovieController() -> UIViewController {
print("createMovieController")
let view = MovieVC()
let movieService = APIClient()
let interactor = MovieInteractor(movieService: movieService)
let presenter = MoviePresenter(
view: view,
interactor: interactor,
router: self
)
view.presenter = presenter
print("presenter: (presenter)")
interactor.delegate = presenter
return view
}
func pushToMovieDetailScreen(navigationController: UINavigationController) {
}
}
Комментарии:
1. пожалуйста, добавьте код вместо скриншотов
2. @TejaNandamuri, можешь проверить еще раз?
Ответ №1:
Инициализация ViewController завершается до вызова createMovieController между 1-й и 2-й строками здесь:
let wireframe = MovieWireframe()
let movies = wireframe.createMovieController()
За этот короткий промежуток времени представление загрузилось (из-за создания каркаса) с
var presenter: IMoviePresenter?
как ноль (следовательно, почему на мгновение возникла необходимость в вопросительном знаке) и вызвал вызов viewDidLoad «преждевременно» (т. Е. до вызова 2-й строки). Поэтому исключите конструкцию из 2 частей, чтобы она не выполнялась по частям 1) без MovieController, а затем 2) была завершена как 2-й шаг за пределами конструкции MovieWireframe. конструкция из 1 части,а не из 2 частей.