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


156

我决定继续与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.
    }
    */
}

请提出一些建议

Answers:


207

问题

这是由于init?(coder aDecoder: NSCoder)目标上没有初始化程序引起的UIViewController。该方法是必需的,因为UIViewControllerUIStoryboard调用实例化a 。

看看我们如何初始化一个UIViewControllerUIStoryboard,请大家看看这里

为什么Objective-C没问题?

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

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

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


1.第一种方法

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

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

2.第二种方法

删除init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?)你的目标UIViewController将继承所需的所有初始化从超类戴夫·伍德在他指出的回答如下



4
谢谢你 快速跟进...创建TableViewController文件时,Xcode已经包含了init(style: UITableViewStyle) { super.init(style: style) // Custom initialization } 为什么我们有两个 init函数?以及为什么苹果默认不包含第二个init?
Trevor McKendrick 2014年

这与iOS 7或iOS 8无关。这与Swift继承intitializers的方式有关!
Sulthan 2014年

公共初始化(视图:UIViewController,框架:CGRect){self.viewController =视图self.imageName =“” self.actionName =“” super.init(框架:frame)}
scrainie 2015年

第一种方法行得通!我的动态表终于充满了动态单元格!!!都是因为该行fatalError( "init(coder:) has not been implemented")停止了我的应用程序。
何塞·曼努埃尔·阿巴卡·罗德里格斯

25

@ 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的解释。但是,如果子类仅具有便捷的初始化器,那么它将继承超类的初始化器,对吗?
jamiltz 2014年

1
是。仅当您提供自己指定的初始化方法(调用超级初始化的方法)时,才可以防止继承超类初始化方法。然后,您必须通过将它们添加到您的类中并仅调用其超级版本来指定要支持的超级实例(如@ 3r1d的回答)
Dave Wood

在子类中仅具有便利的init()而不具有(指定的)init()会导致编译错误。这是因为便利的init()函数必须在函数定义内调用self.init()。
Ohmy

@narumolPug不正确。您不需要包括指定的init方法。您的子类将从超类继承它们。您仍然可以致电self.init()执行超级版本。
戴夫·伍德

视频的确切时刻可以在此处找到youtu.be/W1s9ZjDkSN0?t=2030
Honey

10

对于swift遇到同样问题的人UICollectionViewCells,请将@ 3r1d建议的代码添加到自定义UICollectionViewCell类中,而不要添加到View Controller中:

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

您指的是哪个UICollectionViewCell?用编码器初始化是初始化viewController的方法
E-Riddie 2014年

在此示例中不是,但是万一有人遇到问题(我确实)...如果尝试使用UICollectionViewController,则在自定义单元.swift文件中,需要使用编码器进行初始化。
Nick Yap

2
您需要添加使用实例化这样的代码,每次stackoverflow.com/questions/24035984/...
E-Riddie

3

对于那些需要在Swift中编写代码的人:

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

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


3

我在程序化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)
}

一旦添加,错误就消失了


1

与其添加一些使内部机制正常工作的方法,不如将属性定义为@lazy并在类范围内对其进行初始化。


您还可以通过声明您的属性为可选?
朱利安·B。
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.