ios - 演示者在 VIPER 项目中给出零错误
问题描述
在我用 Viper 做的项目中,ViewController 中的 Presenter 给出了一个 nil 错误。这是什么原因?我该如何解决这个问题?
应用委托
let wireframe = MovieWireframe()
let movies = wireframe.createMovieController()
window = UIWindow(frame: UIScreen.main.bounds)
window?.rootViewController = UINavigationController(rootViewController: movies)
window?.makeKeyAndVisible()
视图控制器
Presenter here 给出了一个 nil 错误。
var presenter: IMoviePresenter? //Nil
override func viewDidLoad() {
super.viewDidLoad()
presenter?.startFetchingMovies() //Nil
}
主持人
此处的 StartFetchingMovies 不起作用,因为 Presenter 为 nil。
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) {
}
}
解决方案
ViewController 的初始化在 createMovieController 在这里的第一行和第二行之间被调用之前完成:
let wireframe = MovieWireframe()
let movies = wireframe.createMovieController()
在这段短暂的时间里,视图加载(由于创建线框)
var presenter: IMoviePresenter?
为 nil (因此为什么暂时需要问号)并导致 viewDidLoad 被“过早”调用(即,在调用第二行之前)。因此,消除 2 部分构造,这样就不会在 1) 没有 MovieController 的情况下零碎完成,然后 2) 作为 MovieWireframe 构造之外的第二步完成。1 部分结构不是 2 部分。
推荐阅读
- postgresql - postgres数据与同一张表中的多个服务器同步
- ruby-on-rails - 如何在点击 ruby on rails 时从下拉列表中获取选定的值?
- angular - 如何在使用 observable 更新数组时更新 *ngFor 以及如何在网站加载时初始化 observable?
- typo3 - TYPO3 routeEnhancers 在根页面上带有后缀“.html”
- java - 在 UPDATE 语句中绑定和添加参数:PostgreSQL
- javascript - 带有 Javascript 的 WebView 不断重新加载
- text-to-speech - iOS 13 Text To Speech (TTS - AVSpeechSynthesisVoice) 在更新后对某些用户崩溃
- ethereum - 错误:所需的气体超过限额或总是失败的交易 - web3js
- sql - 在左连接后从两列的串联中选择
- amazon-s3 - 如何从 URL 将数据导入 Amazon S3