この宣言の両方
protocol SomeProtocol : AnyObject {
}
そしてこの宣言
protocol SomeProtocol : class {
}
クラスだけがこのプロトコルに準拠できるように(つまり、プロトコルのインスタンスがオブジェクトへの参照であるように)構成されているように見え、他の影響はありません。
それらの間に違いはありますか?一方が他方よりも優先されるべきですか?そうでない場合、なぜ同じことをする2つの方法があるのですか?
最新のXcode 6.3.1を使用しています。
これは、公式のSwift dev(Slava_Pestov) Swift forums によって回答されました。概要は次のとおりです:
AnyObject
(protocol SomeProtocol: AnyObject
)。
AnyObject
とclass
は同等です。違いはありません。
class
は、最終的には廃止される予定です。回答 https://forums.Swift.org/t/class-only-protocols-class-vs-anyobject/11507/4 については、この回答は非推奨です。これらの言葉は今も同じです。
[〜#〜]非推奨[〜#〜]
更新: べき乗 を参照した後、2つの定義はと同等と見なされ、AnyObject
が代用として使用され、class
は終了しています。将来、後者は前者を取り除くでしょうが、今のところ、いくつかの小さな違いがあります。
違いは、@objc
宣言のセマンティクスにあります。 AnyObject
では、準拠するクラスが適切なObjective-Cオブジェクトである場合とそうでない場合がありますが、言語はそれらをそのように扱います(静的ディスパッチを失う場合があるため)。これからのポイントは、AnyObject
などを処理できることです。 STLのAnyObject
のドキュメントの例に示すように、@objc
メンバー関数を要求する方法としてのプロトコル制約:
import Foundation
class C {
@objc func getCValue() -> Int { return 42 }
}
// If x has a method @objc getValue()->Int, call it and
// return the result. Otherwise, return nil.
func getCValue1(x: AnyObject) -> Int? {
if let f: ()->Int = x.getCValue { // <===
return f()
}
return nil
}
// A more idiomatic implementation using "optional chaining"
func getCValue2(x: AnyObject) -> Int? {
return x.getCValue?() // <===
}
// An implementation that assumes the required method is present
func getCValue3(x: AnyObject) -> Int { // <===
return x.getCValue() // x.getCValue is implicitly unwrapped. // <===
}
これをclass
- derivingプロトコルに変更すると、同じ例がすぐに失敗します。
import Foundation
protocol SomeClass : class {}
class C : SomeClass {
@objc func getCValue() -> Int { return 42 }
}
// If x has a method @objc getValue()->Int, call it and
// return the result. Otherwise, return nil.
func getCValue1(x: SomeClass) -> Int? {
if let f: ()->Int = x.getCValue { // <=== SomeClass has no member 'getCValue'
return f()
}
return nil
}
// A more idiomatic implementation using "optional chaining"
func getCValue2(x: SomeClass) -> Int? {
return x.getCValue?() // <=== SomeClass has no member 'getCValue'
}
// An implementation that assumes the required method is present
func getCValue3(x: SomeClass) -> Int { // <===
return x.getCValue() // <=== SomeClass has no member 'getCValue'
}
したがって、class
はAnyObject
のより保守的なバージョンであり、動的なメンバーのルックアップやObjective-Cブリッジングではなく、参照セマンティクスのみに関心がある場合に使用する必要があるようです。
プロトコル用のSwiftプログラミング言語ガイド のClass-Only Protocolsセクションの下。 AnyObject
についてのみ言及し、class
については言及していません。
AnyObjectプロトコルをプロトコルの継承リストに追加することで、プロトコルの採用をクラスタイプ(構造体や列挙型ではない)に制限できます。
protocol SomeClassOnlyProtocol: AnyObject, SomeInheritedProtocol {
// class-only protocol definition goes here
}
そのため、新しいコードや新しいプロジェクトにはAnyObject
よりもclass
を使用することをお勧めします。それ以外は、はっきりとした違いはありません。
AnyObject
は、すべてのクラスが暗黙的に準拠するプロトコルです( source )。だから私は違いはないと言います:あなたはクラス制約を要求するためにどちらを使うこともできます。
Xcode 9でprotocol P: class {}
などの行でclass
のヘルプを開く(alt-クリック)と、typealias AnyObject
が表示されます。
したがって、(Swift 4で)コンパイルされたコードは、プロトコルをclass
またはAnyObject
に制限するかどうかに関係なく同じになります。
そうは言っても、styleおよびfuture optionsの問題もあります—将来のSwiftバージョンでは、class
とAnyObject
を別の方法で処理する必要があるかもしれません微妙な方法で、たとえ今はそうではないとしても。
前に間違えた。 @MartinRは私に修正して正しい情報を提供してくれたので、これに本当に答えるべきです。
realの違いは、クラス修飾子を持つプロトコルはクラスにのみ適用でき、構造体や列挙型には適用できないことです。
マーティン、答えてみてください、そしてOPはあなたの答えを受け入れることができますか?