"фатальная ошибка: массив не может быть соединен с Objective-C" - почему вы даже пытаетесь, Swift?


я объявил протокол Swift:

protocol Option {
    var name: String { get }
}

Я объявляю несколько реализаций этого протокола-некоторые классы, некоторые перечисления.

у меня есть контроллер вида со свойством, объявленным так:

var options: [Option] = []

когда я пытаюсь установить это свойство в массив объектов, реализующих Option протокол в другом ВК prepareForSegue, Я получаю ошибку времени выполнения:

fatal error: array cannot be bridged from Objective-C

почему это не работает? Компилятор имеет всю необходимую информацию, и я не понимаю, что Objective-C вообще имеет к этому отношение-мой проект содержит только Swift-файлы, и эти массивы не входят и не выходят из каких-либо методов фреймворка, которые потребовали бы их подключения к NSArray.

4 91

4 ответа:

Я нашел решение. Вполне... неудовлетворительно, но он работает. Где я устанавливаю массив на контроллер вида назначения я делаю:

destinationViewController.options = options.map({ as Option})

компилятор знает, что я передаю в массиве вещей, которые реализуют Option

вы проговорились там очень показательное замечание, которое предполагает источник проблемы. "Массив вещей, которые реализуют Option", не является массивом Option.

проблема с типом options назад в точку, где вы его создаете (в prepareForSegue). Вы не показываете этот код, но я держу пари, что вы не можете бросить / ввести его в этот момент. Вот почему задание не выполняется. options может быть массив вещей, которые на самом деле случается принять вариант, но этого недостаточно; это должно быть набрал как массив параметров.

, так что 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

(I также Проверено это в реальном приложении с фактическим prepareForSegue, и она отлично работает.)

у меня была такая же проблема, и я исправил ее, отметив мой протокол с @objc, в вашем случае это будет выглядеть так

@objc protocol Option {
    var name: String { get }
}

получил решение от ответ

этот тоже отлично работает

destinationViewController.options = options.map{}