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

我决定和斯威夫特继续我剩下的项目。当我将自定义类(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.
}
*/
}

请给点建议

92050 次浏览

问题

这是由于目标 UIViewController上缺少初始化器 init?(coder aDecoder: NSCoder)造成的。这个方法是必需的,因为从 UIStoryboard实例化一个 UIViewController调用它。

要了解如何从 UIStoryboard初始化 UIViewController,请看一下 给你

为什么 Objective-C 不存在这个问题呢?

因为 目标 C会自动继承所有必需的 UIViewController初始值设定项。

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

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


解决方案

第一种方法

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

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

第二种方法

删除目标 UIViewController上的 init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?)将从超类继承所有必需的初始化器,如下面 Dave Wood指出的 回答


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

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

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

注意: 请参阅 WWDC 2014年第403次会议“中级雨燕”在大约33:50的关口了解更多细节。

对于有同样问题的人,可以将@3r1d 建议的代码添加到自定义的 UICollectionViewCell类中,而不是添加到视图控制器中:

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

与其添加一些方法来使内部机制正常工作,不如将我的属性定义为@Lazy,并在 class 作用域中对它们进行初始化。

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

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

这是老版本的 Swift 可能已经不能用了。

我在一个程序化的 CollectionView 单元格中遇到了这个问题,尽管这个操作询问的是一个风险投资,但是在搜索答案的时候我还是遇到了这个问题。对我来说,问题是我确实有

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)
}

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