Kesalahan fatal: penggunaan inisialisasi initializer yang tidak diimplementasikan (coder :) 'untuk kelas


157

Saya memutuskan untuk melanjutkan proyek saya yang tersisa dengan Swift. Ketika saya menambahkan kelas khusus (subclass of UIViewcontroller) ke controller tampilan storyboard saya dan memuat proyek, aplikasi tiba-tiba crash dengan kesalahan berikut:

kesalahan fatal: penggunaan inisialisasi initializer 'init (coder :)' yang tidak diterapkan untuk kelas

Ini adalah kode:

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.
    }
    */
}

Tolong sarankan sesuatu

Jawaban:


208

Isu

Ini disebabkan oleh tidak adanya initializer init?(coder aDecoder: NSCoder)pada target UIViewController. Metode itu diperlukan karena instantiating UIViewControllerdari UIStoryboardpanggilan itu.

Untuk melihat bagaimana kami memulai UIViewControllerdari UIStoryboard, silakan lihat di sini

Mengapa ini bukan masalah dengan Objective-C?

Karena Objective-C secara otomatis mewarisi semua UIViewControllerinisialisasi yang diperlukan .

Mengapa Swift tidak secara otomatis mewarisi inisialisasi?

Swift secara default tidak mewarisi inisialisasi karena keselamatan. Tapi itu akan mewarisi semua inisialisasi dari superclass jika semua properti memiliki nilai (atau opsional) dan subkelas belum mendefinisikan inisialisasi yang ditunjuk.


Larutan

1. Metode pertama

Menerapkan init?(coder aDecoder: NSCoder)target secara manualUIViewController

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

2. Metode kedua

Menghapus init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?)target Anda UIViewControllerakan mewarisi semua inisialisasi yang diperlukan dari superclass sebagai Dave Wood menunjuk pada jawabannya di bawah ini



4
Terima kasih untuk ini. Tindak lanjut cepat ... Saat Anda membuat file TableViewController, Xcode sudah menyertakan init(style: UITableViewStyle) { super.init(style: style) // Custom initialization } Mengapa kita bisa memiliki dua fungsi init? Dan tahu mengapa Apple tidak memasukkan init ke-2 secara default?
Trevor McKendrick

Ini tidak ada hubungannya dengan iOS 7 atau iOS 8. Ini terhubung dengan cara Swift mewarisi inisialisasi!
Sulthan

init publik (tampilan: UIViewController, bingkai: CGRect) {self.viewController = lihat self.imageName = "" self.actionName = "" super.init (bingkai: bingkai)}
scrainie

Metode pertama berhasil! Tabel dinamis saya akhirnya diisi dengan sel dinamis !!! Semua karena saluran fatalError( "init(coder:) has not been implemented")menghentikan aplikasi saya.
Jose Manuel Abarca Rodríguez

26

Opsi lain selain @ 3r1d adalah untuk menghapus metode init berikut dari kelas Anda:

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

Termasuk metode init, mencegah sub class mewarisi init(coder aDecoder: NSCoder!)dari super class-nya. Dengan tidak memasukkannya, kelas Anda akan mewarisi keduanya.

Catatan: Lihat WWDC 2014 Sesi 403 "Intermediate Swift" di sekitar tanda 33:50 untuk detail lebih lanjut.


Terima kasih telah menunjukkan penjelasan pada Sesi 403. Tetapi jika kelas anak hanya memiliki inisialisasi kenyamanan maka itu akan mewarisi inisialisasi kelas super kan?
jamiltz

1
Iya. Anda hanya mencegah metode init kelas super agar tidak diwarisi jika Anda memberikan metode init yang Anda tetapkan sendiri (metode yang memanggil init super). Maka Anda harus menentukan init super mana yang didukung dengan menambahkannya ke kelas Anda dan cukup memanggil versi super (seperti dalam jawaban @ 3r1d)
Dave Wood

Hanya memiliki init () tanpa (ditunjuk) init () di kelas anak Anda akan menyebabkan kesalahan kompilasi. Itu karena kenyamanan fungsi init () harus memanggil self.init () di dalam definisi fungsi.
Ohmy

@narumolPug Itu tidak benar. Anda tidak perlu memasukkan initmetode yang ditunjuk . Kelas anak Anda akan mewarisinya dari kelas super. Anda masih dapat menelepon self.init()yang akan menjalankan versi super.
Dave Wood

Saat yang tepat dari video dapat ditemukan di sini youtu.be/W1s9ZjDkSN0?t=2030
Honey

10

Untuk orang-orang yang memiliki masalah yang sama dengan swift UICollectionViewCells, tambahkan kode yang disarankan @ 3r1d ke UICollectionViewCellkelas khusus Anda dan bukan ke View Controller:

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

UICollectionViewCell mana yang Anda maksud? Init dengan coder adalah cara untuk init pada viewController
E-Riddie

Tidak dalam contoh ini tetapi jika ada orang yang memiliki masalah dengan itu (saya lakukan) ... jika Anda mencoba menggunakan UICollectionViewController, dalam file .swift sel kustom Anda, Anda perlu memasukkan init dengan coder.
Nick Yap

2
Anda perlu menambahkan kode ini setiap kali Anda menggunakan cara instantiation ini stackoverflow.com/questions/24035984/…
E-Riddie

3

Bagi yang membutuhkan kode di Swift:

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

[Sunting] Ini untuk versi Swift yang lebih lama. Mungkin tidak berfungsi lagi.


3

Saya punya masalah ini dalam sel koleksiView terprogram dan meskipun op bertanya tentang vc saya masih mendarat pada pertanyaan ini ketika mencari jawaban. Bagi saya masalahnya adalah saya memang punya

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

diimplementasikan sehingga jawaban teratas tidak bekerja. Apa yang tidak saya miliki di dalam sel adalah inisialisasi:

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

Setelah saya menambahkannya kesalahan itu hilang


1

Daripada menambahkan beberapa metode untuk membuat mekanisme internal berfungsi dengan baik, saya akan pergi dengan mendefinisikan atribut saya sebagai @ lazy dan menginisialisasi mereka tepat di ruang lingkup kelas.


Anda juga dapat mendeklarasikan properti Anda sebagai opsional melalui ?.
Julian B.
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.