NSCoding требует инициализатора в унаследованных классах в Swift

У меня есть класс Foo, который соответствует NSCoding и NSCoding которые я хочу сохранить в NSKeyedArchiver Я хочу создать класс Bar, подкласс Foo, который также будет соответствовать NSCoding и NSCoding . У меня возникла проблема с пониманием того, как создать required convenience init?(coder aDecoder: NSCoder) в подклассе.

поэтому класс Foo …

 class Foo: NSObject, NSCoding { let identifier:String init(identifier:String) { self.identifier = identifier } override var description:String { return "Foo: \(identifier)" } func encodeWithCoder(aCoder: NSCoder) { aCoder.encodeObject(identifier, forKey: "identifier") } required convenience init?(coder aDecoder: NSCoder) { guard let identifier = aDecoder.decodeObjectForKey("identifier") as? String else { return nil } self.init(identifier:identifier) } } 

Затем класс Bar …

 class Bar:Foo { let tag:String init(identifier:String, tag:String) { self.tag = tag super.init(identifier: identifier) } override var description:String { return "Bar: \(identifier) is \(tag)" } } 

Я могу получить это, чтобы скомпилировать, добавив следующие методы, чтобы сделать этот NSCoding совместимый

  override func encodeWithCoder(aCoder: NSCoder) { aCoder.encodeObject(tag, forKey: "tag") super.encodeWithCoder(aCoder) } 

это имеет смысл, потому что я называю super.encodeWithCoder(...) повторное использование супер делает это СУХОЙ. Проблема, с которой я сталкиваюсь, заключается в создании required convenience init?(...) единственный способ, с помощью которого я могу его компилировать, – это сделать это …

  required convenience init?(coder aDecoder:NSCoder) { guard let identifier = aDecoder.decodeObjectForKey("identifier") as? String, let tag = aDecoder.decodeObjectForKey("tag") as? String else { return nil } self.init(identifier:identifier, tag:tag) } 

Я в основном скопировал требуемый инициализатор суперкласса, а затем добавил дополнительный метод декодирования для свойства подкласса. Этот подход не кажется правильным …

Есть ли лучший способ реализовать это?

Сразу после декодирования и назначения всех свойств подкласса в требуемом методе init вызовите:

 super.init(coder: aDecoder) 

Я попробовал свой код на детской площадке, он просто автоматически добавляет код, когда я отмечаю красный круг ошибки.

Кодирование походит на вашу функцию, необходимую для удобства init.

образец кода:

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

Подумайте об этом некоторое время и верьте, что это правильный способ реализовать это.

Причина в том, что Swift обеспечивает инициализацию объекта. Инициализаторы удобства могут вызывать только требуемые инициализаторы. Только требуемый инициализатор может вызвать init на super .

Поэтому единственный способ инициализировать объект подкласса – это декодировать все требуемые параметры инициализации, прежде чем вы вызовете требуемый инициализатор подкласса … который затем вызывает инициализатор суперкласса

Вот код, который вы можете скопировать на площадку https://gist.github.com/vorlando/dc29ba98c93eaadbc7b1

  • Обнаружение кранов в подсмотре в UIScrollView * и * игнорирование жестов жесты
  • Передача данных из представлений в основных данных
  • SDK для iOS (iPhone / iPad) - использование анализатора JSON с использованием user_timeline в Twitter
  • Каков самый быстрый способ сделать много вызовов NSRange в очень длинном NSString на iOS?
  • Двухпозиционный триггер IOS 2 раза
  • Невозможно изменить позицию subview в UITableViewCell
  • Как правильно использовать фреймворк Photos в iOS 8 с UICollectionView, сохраняя пропорции изображения, например, в Messages.app?
  • Правильный способ инициализации состояния в контроллере целевого представления из segue?
  • iOS 8: Как реализовать контроллер вращающегося представления поверх приложения только для портрета?
  • Панель воспроизведения музыки
  • Где применять настройку приложения для отображения UITableViewCell / пользовательской ячейки
  • Interesting Posts

    Как отклонить контроллер модального просмотра, сдвинув его (ака панорамирования)?

    Получение фактического размера в Swift / IOS

    Статический анализатор Xcode 5 висит

    Назначение «id <NSXMLParserDelegate>» из несовместимого типа «FBXMLHandler»?

    Уровень одобрения App Store для приложений для приложений trigger.io

    внедрение GTScrollNavigationBar в быстром

    Обновление обеих сторон контроллера UISplitView

    Настройка IP-адреса iPad программным способом

    Сценарий движения жесты в режиме Scenekit слишком быстро

    Не удалось получить данные и использовать их в UIBarButton – Firebase Swift 3

    Отключить выбор ячейки без UserInteractionEnabled в Swift

    Как правильно настроить CoreData datamodel и NSManagedObjects для отношения ко многим?

    iOS Проверьте, зарегистрирована ли учетная запись iTunes

    неподдерживаемый код ошибки URL-1002

    Дублированные данные загрузки фильма при использовании AVPlayer и Как остановить загрузку данных фильма

    Давайте будем гением компьютера.