1

アレイと組み合わせた Swift プロトコルで多くの問題を抱えていましたが、問題が遊び場で壊れ始める前に、問題全体を再現することさえできませんでした。これは最小限の例です。

Bus2 つのプロトコルと、いずれかのプロトコルへの準拠を宣言するクラスがあります。さらに、 の空の拡張はBus、他のプロトコルへの準拠を宣言します。

import Foundation

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

@objc
protocol Utterable { var utterance: String {get} }

class Bus : Displayable { var name = "a bus"; var utterance = "this is a bus"}

extension Bus : Utterable {}

var bus1 = Bus() // this line fails with EXC_BAD_INSTRUCTION

コンソール出力はランダムに見えるかもしれませんが、そうではありません。のインスタンスを作成しようとすると、一貫して取得されますBus:

objc[9658]: Method cache corrupted. This may be a message to an invalid object, or a memory error somewhere else.
objc[9658]: unused 0x0, SEL 0x10e4ce130, isa 0x1181f9ad0, cache 0x1181f9ae0, buckets 0x7fc491501060, mask 0x0, occupied 0x0
objc[9658]: unused 0 bytes, buckets 64 bytes
objc[9658]: selector 'resolveInstanceMethod:'
objc[9658]: isa '__lldb_expr_1314.Bus'
objc[9658]: Method cache corrupted.
  • @objcすべての属性をコメントアウトすると、エラーはなくなります
  • 準拠していない場合、エラーはなくなりUtterableます。extension Bus: Utterable{}

私のプロトコルに属性が必要な理由@objcは、そうしないと Obj-c ランタイムが次のようなことをしようとしたときに文句を言っvar myDisplayables: [Displayable] = [ Bus() ]たり、プロトコルへの準拠を動的にチェックしたりするためです。

繰り返しますが、これは最小限の例であることに注意してください。

Swift 1.2 で更新: 現在は修正されているようです。Xcode は、「プロトコルが必要とするため」、これらの変更を提案しています。

class Bus : Displayable { @objc var name = "a bus"; @objc var utterance = "this is a bus"}
4

1 に答える 1

1

Utterable問題は、具象クラスに既に実装されているプロパティを持つプロトコルに関するものだと思います。

ご存じのとおり、拡張機能は格納されたプロパティを定義できません (計算のみ)。拡張機能でプロトコルを採用すると、何か問題が発生します。これは明らかにバグです (問題なく動作するか、コンパイラがコンパイル エラーを発生させる必要があります)。

これを修正するには、拡張ではなくクラス宣言でプロトコルを採用するだけです。

class Bus : Displayable, Utterable { var name = "a bus"; var utterance = "this is a bus"}

extension Bus  {}

驚いたことに、utteranceプロパティを計算されたものに変換し、拡張本体に移動します。

extension Bus : Utterable {
    var utterance: String { return "this is a bus" }
}

問題を解決しません - それでも同じエラーです。私はそれがバグであるという証拠と考えています。

于 2015-01-24T23:00:31.400 に答える