web-dev-qa-db-ja.com

swiftプロトコル 'weak'は非クラスタイプに適用できません

私は少し混乱しています。 protocol A : class { ... }protocol A{ ... }の違いは何ですか、swiftでどちらを使用する必要がありますか?

PS:このように書いたときにエラーが発生しました

protocol A{ ... }

weak var delegate: A

エラー: 'weak'は非クラス型に適用できません

34
boog
protocol A : class { ... }

"class-only protocol" を定義します:このプロトコルを採用できるのは(構造体または列挙型ではなく)クラス型のみです。

弱い参照は、参照タイプに対してのみ定義されます。クラスは参照型であり、構造と列挙は値型です。 (クロージャも参照タイプですが、クロージャはプロトコルを採用できないため、このコンテキストでは無関係です。)

したがって、プロトコルに準拠するオブジェクトを弱いプロパティに格納する必要がある場合、そのプロトコルはクラスのみのプロトコルである必要があります。

クラス専用プロトコルを必要とする別の例を次に示します。

protocol A { 
    var name : String { get set }
}

func foo(a : A) {
    a.name = "bar" // error: cannot assign to property: 'a' is a 'let' constant
}

これはコンパイルされません。なぜなら、構造体と列挙のインスタンスでは、a.name = "bar"aの突然変異です。プロトコルを次のように定義する場合

protocol A : class { 
    var name : String { get set }
}

コンパイラーは、aがクラス型のインスタンスであり、aがオブジェクトストレージへの参照であり、a.name = "bar"は参照オブジェクトを変更しますが、aは変更しません。

したがって、一般に、プロトコルを採用する型が値型ではなく参照型である必要がある場合は、クラスのみのプロトコルを定義します。

76
Martin R

NSObjectやAnyObjectなどのクラスタイプからプロトコルを派生させることができます。例:

protocol TopNewsTableDelegate  : AnyObject{
  func topNewsTableDidLoadedStories()
}
2

または、次のように入力できます

@objc protocol A { ... }

その後、弱いデリゲート参照を作成できます

0
Medhat Mebed