【问题标题】:Fatal error: use of unimplemented initializer 'init(coder:)' for class致命错误:对类使用未实现的初始化程序“init(coder:)”
【发布时间】:2014-07-25 01:00:12
【问题描述】:

我决定用 Swift 继续我剩下的项目。当我将自定义类(UIViewcontroller 的子类)添加到我的故事板视图控制器并加载项目时,应用程序突然崩溃并出现以下错误:

致命错误:对类使用未实现的初始化程序“init(coder:)”

这是代码:

import UIKit

class TestViewController: UIViewController {

    init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?) {
        super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
        // Custom initialization
    }

    override func viewDidLoad() {
        super.viewDidLoad()
              // Do any additional setup after loading the view.
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    /*
    // #pragma mark - Navigation

    // In a storyboard-based application, you will often want to do a little preparation before navigation
    override func prepareForSegue(segue: UIStoryboardSegue?, sender: AnyObject?) {
        // Get the new view controller using [segue destinationViewController].
        // Pass the selected object to the new view controller.
    }
    */
}

请提出建议

【问题讨论】:

    标签: ios macos uiviewcontroller swift


    【解决方案1】:

    问题

    这是由目标 UIViewController 上缺少初始化程序 init?(coder aDecoder: NSCoder) 引起的。该方法是必需的,因为从 UIStoryboard 实例化 UIViewController 会调用它。

    要了解我们如何从UIStoryboard 初始化UIViewController,请查看here

    为什么这不是 Objective-C 的问题?

    因为 Objective-C 自动继承了所有必需的 UIViewController 初始化器。

    为什么 Swift 不自动继承初始化器?

    Swift 出于安全考虑,默认情况下不继承初始化器。但是如果所有属性都有一个值(或可选)并且子类没有定义任何指定的初始化器,它将继承父类的所有初始化器。


    解决方案

    1。第一种方法

    在目标UIViewController上手动实现init?(coder aDecoder: NSCoder)

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }
    

    2。第二种方法

    删除目标 UIViewController 上的 init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?) 将继承父类中所有必需的初始化程序,正如 Dave Wood 在下面的 answer 中指出的那样


    【讨论】:

    • 谢谢。快速跟进... 当你创建 TableViewController 文件时,Xcode 已经包含init(style: UITableViewStyle) { super.init(style: style) // Custom initialization } 为什么我们可以有两个 init 函数?知道为什么 Apple 默认不包含第二个 init 吗?
    • 这与iOS 7或iOS 8无关。这与Swift继承初始化程序的方式有关!
    • public init(view: UIViewController, frame: CGRect) { self.viewController = view self.imageName = "" self.actionName = "" super.init(frame: frame) }
    • 第一种方法奏效了!我的动态表格终于填满了动态单元格!!!都是因为fatalError( "init(coder:) has not been implemented") 这条线停止了我的应用程序。
    【解决方案2】:

    除了@3r1d 的另一个选项是从你的类中删除以下 init 方法:

    init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?) {
        super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
        // Custom initialization
    }
    

    包括该 init 方法,可防止子类从其超类继承 init(coder aDecoder: NSCoder!)。如果不包含它,您的类将继承两者。

    注意:有关更多详细信息,请参阅 WWDC 2014 Session 403 “Intermediate Swift”,时间约为 33:50。

    【讨论】:

    • 感谢您指出对 Session 403 的解释。但是如果子类只有便捷初始化器,那么它将继承超类初始化器对吗?
    • 是的。如果您提供自己指定的 init 方法(那些调用超级 init 的方法),则只能防止继承超类的 init 方法。然后,您必须通过将它们添加到您的类并调用超级版本来指定要支持的超级版本(如@3r1d 的回答)
    • 在您的子类中只使用方便的 init() 而没有(指定的)init() 将导致编译错误。这是因为方便的 init() 函数必须在函数定义中调用 self.init()。
    • @narumolPug 这是不正确的。您不需要包含指定的init 方法。您的子类将从超类继承它们。您仍然可以调用self.init(),它将执行超级版本。
    • 视频的确切时刻可以在这里找到youtu.be/W1s9ZjDkSN0?t=2030
    【解决方案3】:

    对于与 swift UICollectionViewCells 有相同问题的人,请将 @3r1d 建议的代码添加到您的自定义 UICollectionViewCell 类而不是视图控制器中:

    init(coder aDecoder: NSCoder!)
    {
        super.init(coder: aDecoder)
    }
    

    【讨论】:

    • 你指的是哪个 UICollectionViewCell? Init with coder 是初始化viewController的方式
    • 不在这个例子中,但如果有人有问题(我做过)......如果你尝试使用 UICollectionViewController,在你的自定义单元格 .swift 文件中,你需要将 init 与 coder .
    • 每次使用这种实例化方式都需要添加这段代码stackoverflow.com/questions/24035984/…
    【解决方案4】:

    对于那些需要 Swift 代码的人:

    required init(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }
    

    [编辑] 这是针对旧版本的 Swift 的。可能不再起作用了。

    【讨论】:

      【解决方案5】:

      我在一个程序化的 collectionView 单元格中遇到了这个问题,即使操作员询问了一个 vc,我在搜索答案时仍然遇到了这个问题。对我来说,问题是我确实有

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

      已实施,因此最佳答案无效。我在单元格中没有的是初始化程序:

      // my programmatic cell was missing this
      override init(frame: CGRect) {
          super.init(frame: frame)
      }
      

      一旦我添加它,错误就消失了

      【讨论】:

        【解决方案6】:

        我不会添加一些方法来使内部机制正常工作,而是将我的属性定义为 @lazy 并在类范围内初始化它们。

        【讨论】:

        • 您还可以通过? 将您的属性声明为可选。
        猜你喜欢
        • 1970-01-01
        • 2017-03-22
        • 2019-04-23
        • 1970-01-01
        • 1970-01-01
        • 2022-01-23
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多