Swiftプロトコル:
protocol Option {
var name: String { get }
}
このプロトコルの複数の実装を宣言します—いくつかのクラス、いくつかの列挙型。
次のように宣言されたプロパティを持つView Controllerがあります:
var options: [Option] = []
このプロパティを別のVCのOption
プロトコルでprepareForSegue
プロトコルを実装するオブジェクトの配列に設定しようとすると、ランタイムエラーが発生します。
fatal error: array cannot be bridged from Objective-C
なぜこれが機能しないのですか?コンパイラには必要なすべての情報があり、Objective-Cがそれとどう関係するのかまったくわかりません。私のプロジェクトにはSwiftファイルのみが含まれており、これらの配列は提供されていませんNSArray
へのブリッジを必要とするフレームワークメソッドの内外で。
私は解決策を見つけました。それはかなり... 不満足ですが、動作します。目的のView Controllerで配列を設定する場所:
destinationViewController.options = options.map({$0 as Option})
コンパイラは、Optionを実装するものの配列を渡すことを知っています
あなたはそこにスリップして、問題の原因を示唆する非常に明快な発言をさせました。 「オプションを実装するものの配列」は、オプションの配列ではありません。
問題は、options
を作成した時点(prepareForSegue
内)のタイプにあります。あなたはそのコードを表示しませんが、その時点であなたがそれをキャスト/タイプすることに失敗することを賭けています。それが割り当てが失敗する理由です。 options
は実際にOptionを採用することの配列ですが、それだけでは十分ではありません。 Optionの配列としてtypedでなければなりません。
したがって、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
を使用して実際のアプリでテストしたところ、正常に動作します。)
私は同じ問題を抱えていたので、プロトコルを@objc
、あなたの場合は次のようになります
@objc protocol Option {
var name: String { get }
}
この答え から解決策を得た
これも正常に動作します
destinationViewController.options = options.map{$0}