あなたが実装したのとまったく同じです。違いは、メソッドが実際に呼び出される方法になります。
さんはこの非常に簡単な例見てみましょう:
let o: FooProtocol = Omitted()
let oN = o.bar?()
let i: FooProtocol = Implemented()
let iN = i.bar?()
oN
とiN
:他のコードを追加していないことで
@objc protocol FooProtocol {
optional func bar() -> Int
}
class Omitted: NSObject, FooProtocol {}
class Implemented: NSObject, FooProtocol {
func bar() -> Int {
print("did custom bar")
return 1
}
}
を、私のようなこのコードを使用する必要があることを期待したいですどちらも最終的にタイプInt?
,oN
であり、nil
,iN
はであり、我々はte xt "did custom bar"
print。
重要なことに、オプションのチェーンメソッドではない:bar?()
、そのかっこ内のメソッド名の間に疑問符があります。これは、Swiftからオプションのプロトコルメソッドを呼び出す必要があります。
今度は、私たちのプロトコルの拡張を追加してみましょう。
extension FooProtocol {
func bar() -> Int {
print("did bar")
return 0
}
}
我々は、必要に応じてメソッド呼び出しをチェーン私たちの元のコードに固執する場合は、動作中に変更はありません。
は、
しかし、は、プロトコル拡張を使用して、オプションでアンラップする必要はありません。私たちは、アウトアンラップオプションを取ることができ、および拡張が呼び出されます。
ここでの不運な問題はそれがあり、これは必ずしも、特に有用ではないということですか?今度は、毎回拡張機能で実装されているメソッドを呼び出すだけです。
の場合は、の場合は、プロトコルを使用してメソッドを呼び出しているクラスを制御しています。あなたは、クラスセレクタに応答するか否かをチェックすることができます
let i: FooProtocol = Implemented()
if i.respondsToSelector("bar") {
i.bar?()
}
else {
i.bar()
}
これはまた、あなたのプロトコルの宣言を変更しなければならないことを意味:
@objc protocol FooProtocol: NSObjectProtocol
がNSObjectProtocol
を追加私たちはrespondsToSelector
を呼び出すことができます私たちの議定書はまったく変更されません。@objc
というマークの付いたプロトコルを実装するには、すでにNSObject
から継承していなければなりません。
言うまでもなく、Objective-CコードはSwift型でこのロジックを実行することができず、実際にはこれらのプロトコル拡張で実装されたメソッドを実際に呼び出すことはできません。あなたがAppleのフレームワークから拡張メソッドを呼び出すために何かを得ようとしているなら、あなたは運が悪いと思われます。それは、たとえあなたがSwiftでどちらか一方を呼び出そうとしているとしても、それがプロトコルメソッドマークであれば、それは非常に素晴らしい解決策ではありません。
詳細な説明をありがとうございます!したがって、Appleのフレームワークのように 'プロトコル 'を制御できなければ、デフォルト実装を提供できないようです。 – chrisamanse
できます。拡張機能について知らないコードで実際に呼び出される '@ objc'プロトコルの***オプションの***メソッドのデフォルト実装を提供することはできません。エクステンションは知っておかなければなりません* Swiftが(私が知る限り)両方を呼び出す正しいコードを書くことができ、Swiftが拡張機能について知らなかった場合、両方を呼び出す正しいコードがコンパイルされないためです。 – nhgrif
はい。私は*オプション*メソッドを意味しました。ありがとう! – chrisamanse