92

我已经声明了一个 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.

4

4 回答 4

83

我找到了解决方案。这是相当......不令人满意,但它的工作原理。我在目标视图控制器上设置数组的地方是:

destinationViewController.options = options.map({$0 as Option})
于 2015-05-07T12:22:59.297 回答
22

编译器知道我传入了一个实现 Option 的东西数组

你漏掉了一句非常有启发性的话,这表明了问题的根源。“实现选项的事物数组”不是选项数组。

问题在于options您创建它的点的类型(在 中prepareForSegue)。您没有显示该代码,但我敢打赌您当时无法投射/键入它。这就是任务失败的原因。options可能是一系列实际上恰好采用 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,并且效果很好。)

于 2015-05-07T12:44:41.930 回答
16

我遇到了同样的问题并修复了它用 标记我的协议@objc,在你的情况下它看起来像这样

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

从这个答案中得到了解决方案

于 2015-08-13T21:24:26.980 回答
1

这个也很好用

destinationViewController.options = options.map{$0}
于 2016-05-17T15:04:19.627 回答