Ich beschloss, mein verbleibendes Projekt mit Swift-language fortzusetzen. Als ich die benutzerdefinierte Klasse (.Swift-Klasse, die zur UIViewcontroller-Unterklasse gehört) in meinen Storyboard-Viewcontroller einfügte, stürzte die App plötzlich mit folgendem error ab:
schwerwiegender Fehler: Verwendung des unimplementierten Initialisierers 'init (coder :)' für die Klasse
Dies ist ein Code:
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.
}
*/
}
Bitte schlagen Sie etwas vor,
Dies wird durch das Fehlen des Initialisierers init?(coder aDecoder: NSCoder)
auf dem Ziel UIViewController
verursacht. Diese Methode ist erforderlich, weil das Instantiieren einer UIViewController
von einer UIStoryboard
aufgerufen wird.
Um zu sehen, wie wir eine UIViewController
von einer UIStoryboard
initialisieren, schauen Sie bitte hier
Weil Objective-C automatisch alle erforderlichen UIViewController
-Initialisierer erbt.
Swift erbt aus Sicherheitsgründen standardmäßig die Initialisierer nicht. Es werden jedoch alle Initialisierer von der Oberklasse übernommen, wenn alle Eigenschaften einen Wert (oder optional) haben und die Unterklasse keine festgelegten Initialisierer definiert hat.
init?(coder aDecoder: NSCoder)
auf dem Ziel UIViewController
manuell implementieren
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
Wenn Sie init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?)
auf Ihrem Ziel UIViewController
entfernen, werden alle erforderlichen Initialisierer von der Oberklasse übernommen, während Dave Wood auf seine answer zeigt
Eine weitere Option neben @ 3r1d ist das Entfernen der folgenden init-Methode aus Ihrer Klasse:
init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?) {
super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
// Custom initialization
}
Durch das Einschließen dieser init-Methode wird verhindert, dass die Unterklasse init(coder aDecoder: NSCoder!)
von ihrer Oberklasse erbt. Wenn Sie es nicht einschließen, erbt Ihre Klasse beide.
Hinweis: Weitere Informationen finden Sie in der WWDC 2014 Session 403 "Intermediate Swift" bei ca. 33:50.
Für Personen, die das gleiche Problem mit Swift UICollectionViewCells
haben, fügen Sie den von @ 3r1d vorgeschlagenen Code in Ihre benutzerdefinierte UICollectionViewCell
-Klasse ein und nicht in den View Controller:
init(coder aDecoder: NSCoder!)
{
super.init(coder: aDecoder)
}
Für diejenigen, die den Code in Swift benötigen:
required init(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
[Bearbeiten] Dies war für eine ältere Version von Swift. Funktioniert möglicherweise nicht mehr.
Ich hatte dieses Problem in einer programmatischen collectionView-Zelle, und obwohl die Operation nach einem Vc fragt, bin ich immer noch auf diese Frage gestoßen, als ich nach einer Antwort suchte. Für mich war das Problem das ich hatte
`required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}`
implementiert, so dass die Top-Antwort nicht funktionierte. Was ich nicht in der Zelle hatte, war der Initialisierer:
// my programmatic cell was missing this
override init(frame: CGRect) {
super.init(frame: frame)
}
Nachdem ich es hinzugefügt hatte, ging der Fehler weg
Anstatt einige Methoden hinzuzufügen, mit denen der interne Mechanismus funktioniert, möchte ich meine Attribute als @lazy definieren und sie direkt im Klassenbereich initialisieren.