Неустранимая ошибка: использование не реализованного инициализатора 'init(coder:)' для класса

Я решил продолжить свой оставшийся проект с Swift-language. Когда я добавил пользовательский класс (класс.swift, который подкласс UIViewcontroller) в моем раскадровке viewcontroller и загрузил проект, приложение внезапно завершилось с следующей ошибкой:

фатальная ошибка: использование не реализованного инициализатора '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.
    }
    */
}

Пожалуйста, предложите что-нибудь,

6 ответов

Решение

вопрос

Это вызвано отсутствием инициализатора init?(coder aDecoder: NSCoder) на цель UIViewController, Этот метод требуется, потому что создание экземпляра UIViewController из UIStoryboard называет это

Чтобы увидеть, как мы инициализируем UIViewController из UIStoryboardпожалуйста, посмотрите здесь

Почему это не проблема с 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 будет наследовать все необходимые инициализаторы от суперкласса, как указал Дейв Вуд на свой ответ ниже


Другой вариант, кроме @ 3r1d, - вместо этого удалить следующий метод init из вашего класса:

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

Включение этого метода init предотвращает наследование подкласса init(coder aDecoder: NSCoder!) из своего суперкласса. Не включая его, ваш класс унаследует оба.

Примечание. Для получения более подробной информации см. Сессия 403 WWDC 2014 "Промежуточное стремительное движение", отметка 33:50

Для людей, имеющих ту же проблему с Swift UICollectionViewCells, добавьте код, который @3r1d предложил в ваш пользовательский UICollectionViewCell класс, а не к контроллеру представления:

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

Для тех, кому нужен код в 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)
}

Как только я добавил это, ошибка ушла

Вместо того, чтобы добавлять некоторые методы, чтобы заставить внутренний механизм работать нормально, я бы пошел с определением моих атрибутов как @lazy и инициализировал их прямо в области видимости класса.

Другие вопросы по тегам