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

135

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

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

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

Теги:
uiviewcontroller
macos

5 ответов

192
Лучший ответ

Вопрос

Это вызвано отсутствием инициализатора init?(coder aDecoder: NSCoder) на целевом UIViewController. Этот метод требуется, потому что он вызывает экземпляр a UIViewController из a 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 наследует все необходимые инициализаторы из суперкласса, поскольку Dave Wood указывает на свой ответ ниже


  • 4
    Спасибо за это. Быстрое продолжение ... Когда вы создаете файл TableViewController, Xcode уже включает init(style: UITableViewStyle) { super.init(style: style) // Custom initialization } Почему у нас может быть две функции init? И есть идеи, почему Apple не включает второй init по умолчанию?
  • 0
    Это не имеет ничего общего с iOS 7 или iOS 8. Это связано с тем, что Swift наследует инициализаторы!
Показать ещё 2 комментария
24

Другим вариантом, кроме @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.

  • 0
    Спасибо за указание на объяснение на Сессии 403. Но если дочерний класс имеет только удобные инициализаторы, тогда он унаследует инициализаторы суперкласса, верно?
  • 1
    Да. Вы предотвращаете наследование методов init суперкласса только в том случае, если вы предоставляете свои собственные назначенные методы init (те, которые вызывают super inits). Затем вы должны указать, какой из суперинтеритов поддерживать, добавив их в свой класс и просто вызвав супер версию (как в ответе @ 3r1d)
Показать ещё 3 комментария
9

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

init(coder aDecoder: NSCoder!)
{
    super.init(coder: aDecoder)
}
  • 0
    на какую UICollectionViewCell вы ссылаетесь? Init с кодером - это способ инициализации viewController
  • 0
    Не в этом примере, но в случае, если у кого-то есть проблемы с этим (я сделал) ... если вы пытаетесь использовать UICollectionViewController, в вашем файле .swift вашей ячейки вам нужно поместить init с кодером.
Показать ещё 1 комментарий
3

Для тех, кому нужен код в Swift:

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

[Edit] Это было для старой версии Swift. Возможно, он больше не работает.

0

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

  • 0
    Вы также можете объявить свою собственность как необязательную через ? ,

Ещё вопросы

Сообщество Overcoder
Наверх
Меню