この質問CKRecord
は、Swift で添え字を使用できるかどうかを尋ねます。質問者が望んでいたことを行う方法はすでに知っていましたが、それを順列するたびにスタックオーバーフローが発生します。
subscript(key: String) -> CKRecordValue? {
get {
return objectForKey(key) as CKRecordValue?
}
set {
setObject(newValue, forKey: key)
}
}
ゲッターでスタックオーバーフローが発生します。(セッターは試したことがないのでそちらでも発生するかもしれません。) objectForKey:
、objectForKeyedSubscript:
、 で実装してみましvalueForKey:
た。すべてが同じ結果を生成します: スタック オーバーフロー。
CKRecord
確かにObjective-Cで書かれているので、これは非常に奇妙です。Swift のsubscript
メソッドを再帰的に呼び出すのはなぜですか? 意味がない。Nate Cook は、質問者への回答の中で、なぜ Swift が自動的にブリッジしないのか疑問に思っていobjectForKeyedSubscript:
ます。それを行うためのコードが完全に焼き付けられていない可能性がありますが、この問題を引き起こしています。を持つ別のクラスで試してみる必要がありobjectForKeyedSubscript:
ます。
アップデート
objectForKeyedSubscript:
通常はブリッジされているようです。適切なメソッドを使用して Objective-C でクラスを作成し、それをブリッジング ヘッダーに追加すると、インデクサーがそこにあり、問題なくコンパイルされました。さらに良いことに、スタックオーバーフローなしで機能しました。
これは、 で非常に異常なことが起こっていることを意味しCKRecord
ます。
理論
Swift で、 aをキーとしてメソッドを継承しNSObject
て実装するクラスを作成すると、 this になります。(「純粋な Swift」クラスの場合、これは当てはまらないと思います。) これは、Swift クラスを Objective-C にインポートし、そこにあることを確認することで確認できます。subscript
String
objectForKeyedSubscript:
objectForKeyedSubscript:
からCKRecord
派生しているためNSObject
、実装subscript
するとデフォルトの実装がオーバーライドされます。さらに、objectForKey:
and valueForKey:
all 最終的に呼び出された のように見えますがobjectForKeyedSubscript:
、その結果 (読み取り: "is the same as") が呼び出されsubscript
、スタック オーバーフローが発生します。
これが、スタック オーバーフローが発生する理由を説明している可能性があります。が自動的にブリッジされなかった理由はまだ説明されていませんobjectForKeyedSubscript:
が、おそらく、 の定義がsetObject:forKeyedSubscript:
正規のものとはわずかに異なる型シグネチャを持っているためです- (void)setObject:(id <CKRecordValue>)object forKeyedSubscript:(NSString *)key;
。これは Objective-C と何の違いもありませんが、「ブリッジング コード」につまずく可能性があります。結局のところ、Swift はかなり新しいものです。