Я объявил протокол Swift:
protocol Option {
var name: String { get }
}
Я объявляю несколько реализаций этого протокола - некоторые классы, некоторые перечисления.
У меня есть контроллер представления со свойством, объявленным так:
var options: [Option] = []
Когда я пытаюсь установить это свойство для массива объектов, реализующих Option
протокол в другом VC prepareForSegue
, я получаю ошибку времени выполнения:
fatal error: array cannot be bridged from Objective-C
Почему это не работает? У компилятора есть вся необходимая информация, и я вообще не понимаю, какое отношение к нему имеет Objective-C - мой проект содержит только файлы Swift, и эти массивы не входят или выходят из каких-либо методов фреймворка, которые могли бы заставляют их соединяться NSArray
.
ios
swift
swift-protocols
Роберт Аткинс
источник
источник
@objc
свой протокол? stackoverflow.com/a/28029568/377369Ответы:
Я нашел решение. Это довольно ... неудовлетворительно , но работает. Где я устанавливаю массив на контроллере представления назначения, я делаю:
destinationViewController.options = options.map({$0 as Option})
источник
options as [Option]
Вы произнесли очень показательное замечание, указывающее на источник проблемы. «Массив вещей, реализующих Option» не является массивом Option.
Проблема заключается в том, какой тип
options
спинки находится в том месте, где вы его создаете (вprepareForSegue
). Вы не показываете этот код, но я держу пари, что вы не сможете его ввести / ввести в этот момент. Вот почему задание не выполняется.options
может быть множество вещей, которые действительно могут принять Option, но этого недостаточно; он должен быть набран как массив Option.Итак, вернемся к следующей
prepareForSegue
формеoptions
:let options : [Option] = // ... whatever ...
Теперь вы можете назначить его напрямую
destinationViewController.options
.Вот небольшой тестовый пример (на детской площадке; я ненавижу детские площадки, но они могут найти свое применение):
protocol Option { var name : String {get} } class ViewController : UIViewController { var options : [Option] = [] } enum Thing : Option { var name : String { get { return "hi" } } case Thing } let vc = ViewController() let options : [Option] = [Thing.Thing] vc.options = options // no problem
(Я также тестировал это в реальном приложении с реальным
prepareForSegue
, и он отлично работает.)источник
viewController.options = things as [Option]
), ни создание временной переменной, явно типизированной,[Option]
как вы предлагаете здесь, на самом деле не работают. В обоих случаях я получаю ошибку времени выполнения.У меня была такая же проблема, и я исправил ее, отметив мой протокол
@objc
, в вашем случае это будет выглядеть так@objc protocol Option { var name: String { get } }
Получил решение из этого ответа
источник
Этот тоже отлично работает
destinationViewController.options = options.map{$0}
источник