【问题标题】:Init(coder:) has not ImplementInit(coder:) 没有实现
【发布时间】:2020-06-24 08:58:48
【问题描述】:

我正在使用 VIP Clean 创建应用程序,但在 LoginRouter 上调用 HomeViewController 时遇到问题。

我尝试了几种方法,实例化 homeviewcontroller 并像这样传递 HomeViewController 初始化信息:let homeViewController = HomeViewController(interactor: HomeInteractor(repository: HomeRepository(), user: user), router: HomeRouter(navigationController: navigationController), presenter: HomePresenter())

我收到同样的信息,但我不知道如何解决它......

登录路由器:

import UIKit

@objc protocol LoginRouting{
    func routeToHome(login:LoginViewController, user: UserRealm)
}

protocol LoginDataPassing{
    var dataStore: LoginDataStore? { get }
}
class LoginRouter: NSObject, LoginRouting {
//MARK: - Navigation init

    weak var viewController: LoginViewController?
    var dataStore: LoginDataStore?

    var navigationController = UIViewController()

    init(navigationController: UIViewController){
        self.navigationController = navigationController
    }

     //MARK: - Routing and Navigations

    func routeToHome(login: LoginViewController, user: UserRealm) {
        login.dismiss(animated: true, completion: nil)
    
        let home = 
                UIStoryboard(name:"Main",bundle:nil).instantiateViewController(identifier: 
                "HomeViewController")
    
        UIApplication.topViewController()?.present(home, animated: true, completion: nil)
    
     }
  }

HomeViewController:

import UIKit


protocol HomeDisplayLogic: class{
    func displaySomething(viewModel: Home.ViewModel)
}


class HomeViewController: UIViewController, HomeDisplayLogic {

@IBOutlet weak var usernameLb: UILabel!
@IBOutlet weak var userAccontLb: UILabel!
@IBOutlet weak var userBalance: UILabel!
@IBOutlet weak var tableview: UITableView!




var router: HomeRouter?
private var interector: HomeInteractor
private var presenter: HomePresenter
private var tableViewDataSource: HomeDataSource?

init(interactor: HomeInteractor, router: HomeRouter, presenter: HomePresenter) {
    self.interector = interactor
    self.interector.presenter = presenter
    self.presenter = presenter
    self.router = router
    super.init(nibName: nil, bundle: nil)
}

required init?(coder aDecoder: NSCoder) {
     fatalError("init(coder:) has not been implemented")
  }

 
 // MARK: - View lifecycle



   override func viewDidLoad() {
       
       populateInformations()
       setupView()
           
      }
   
   private func setupView() {
        presenter.viewController = self
          
        HomeDataSource.setupHome(tableView: tableview)
        tableViewDataSource = HomeDataSource(presenter: presenter)
        tableview.dataSource = tableViewDataSource
        tableview.delegate = tableViewDataSource
      }
 
 // MARK: - PopulateInformations
 
 func populateInformations(){
    let request = Home.Request(userId: interector.user.userId ?? "1.0")
    interector.getInfoStatements(request: request)
 }

   func displaySomething(viewModel: Home.ViewModel) {
    
  }

 }

当我打电话给 Home 时,我收到这条消息:Fatal error: init(coder:) has not been implemented: file

有人可以向我解释什么是错误的,或者如何正确地将信息从一个 viewController 传递到另一个?

【问题讨论】:

    标签: ios swift xcode viper-architecture


    【解决方案1】:

    因为您是从情节提要中启动 viewController,所以

    required init?(coder aDecoder: NSCoder)
    

    将被触发。它还没有实现,所以它会崩溃。

    要修复它,您可以从 viewController 中删除这两个 init 方法 然后,您可以将其设置为可选并将其设置为普通属性,而不是从 init 方法设置交互器、路由器。

    【讨论】:

    • 所以,我尝试了您的解决方案,但我无法在正在运行的应用程序中显示信息
    【解决方案2】:

    你正在用你的初始化器做一些非常奇怪的事情......

    编译器抱怨是因为init?(coder aDecoder: NSCoder)init(coder aDecoder: NSCoder) 不同,它不是可选的事实是一个巨大的差异。

    您还拥有自己的带有更多参数的初始化程序,但该初始化程序调用了不使用 coder 值的 super init。你应该打电话给super.init(coder: coder) 甚至self.init(coder: coder)。但就目前而言,UIStoryboard. instantiateViewController 不知道您的自定义初始化程序,因此它甚至不会被调用。

    你有两个选择:

    如果您的目标是 iOS 13 以下,则需要使用 init(coder aDecoder: NSCoder) 并删除您的自定义初始化程序。您还需要将其他变量设为可选,并在创建视图控制器后设置它们的值。

    如果您仅针对 iOS 13+(这意味着您将不支持 iOS 12 及更低版本),you can use this method,它将为您提供 NSCoder 值,您可以将其传递给自定义初始化程序。不过,您仍然需要在两个初始化程序中删除 ?

    它看起来像这样:

    let home = UIStoryboard(name:"Main",bundle:nil).instantiateViewController(identifier: 
                    "HomeViewController") { coder in
      HomeViewController(coder: coder, interactor: interactor, router: router, presenter: presenter)
    }
    

    (我没有在您的代码中看到其余的必需属性,所以我只是输入了它们的名称,但我假设您有办法找到它们)

    【讨论】:

    • 我正在测试这个并且忘记改变它来问这个问题......我会改变它。但是我会测试这个解决方案,但是如果可以使用 IOS 12,是否还有另一种方法可以做到这一点?
    • 我正在测试,但我有相同的消息Fatal error: init(coder:) has not been implemented: file
    • 不,无法在 iOS 12 及更低版本上使用自定义 coder 初始化程序。你崩溃的原因是因为你对init(coder:) 的实现只会抛出一个致命错误。将实际代码放在那里,然后调用super
    • 我明白了,但是我该如何解决呢?我应该在初始化中输入super.init () 还是什么?
    • 这是非常基本的初始化程序,查看或自己尝试一下,与我给你所有必需的代码相比,你会学到更多。
    猜你喜欢
    • 1970-01-01
    • 2022-01-23
    • 1970-01-01
    • 1970-01-01
    • 2018-05-17
    • 2019-09-17
    • 1970-01-01
    • 2016-11-18
    • 2014-07-25
    相关资源
    最近更新 更多