2015-12-26 11 views
5

は私がthis link.類似の条件に基づいてプロトコルを拡張するプロトコルVSに準拠するクラスを拡張することの違いは?

を経たしかし、私は実際には2つのコードスニペットを下回るとの間の論理的な違いを取得いけない:

1.プロトコルErrorPopoverRendererに準拠するもののみUIViewControllersを拡張します。それに準拠するもののみUIViewControllersためのプロトコルを拡張

protocol ErrorPopoverRenderer { 
    func presentError(message: String, withArrow shouldShowArrow: Bool, backgroundColor: UIColor, withSize size: CGSize, canDismissByTappingAnywhere canDismiss: Bool) 
} 

extension UIViewController: ErrorPopoverRenderer { //Make all the UIViewControllers that conform to ErrorPopoverRenderer have a default implementation of presentError 
    func presentError(message: String, withArrow shouldShowArrow: Bool, backgroundColor: UIColor, withSize size: CGSize, canDismissByTappingAnywhere canDismiss: Bool) 
{} 
} 

2。

extension ErrorPopoverRenderer where Self: UIViewController { 
func presentError() { 
} 
} 

のどちらかの方法、プロトコルに準拠する任意のUIViewControllerのサブクラスは、デフォルトのメソッドの実装を持っていますが、のUIViewController拡張子またはプロトコル拡張でます。 論理的な違いは何ですか? 私はまず第一に

答えて

1

間違っている場合、あなたは方法presentError(...)ため青写真とプロトコルErrorPopoverRendererを作成し、私を修正してください。その後、メソッドpresentError(...)の(強制)青写真を実装して、このプロトコルに準拠するようにクラスUIViewControllerを拡張します。

これは、サブクラスに対して追加のプロトコル制約ErrorPopoverRendererを使用してUIViewController)をサブクラス化できることを意味します。 UIViewControllerプロトコルErrorPopoverRendererに準拠するように拡張されていない場合は、リンクされた例では、後続のコードでは、あなたに提示される時エラー(... does not comply to protocol ErrorPopoverRenderer

class KrakenViewController: UIViewController, ErrorPopoverRenderer { 
    func failedToEatHuman() { 
     //… 
     //Throw error because the Kraken sucks at eating Humans today. 
     presentError(ErrorOptions(message: "Oh noes! I didn't get to eat the Human!", size: CGSize(width: 1000.0, height: 200.0))) //Woohoo! We can provide whatever parameters we want, or no parameters at all! 
    } 
} 

しかし、この方法で可能な問題があるコンパイルケースでしょうリンク:

エラービューを に表示するたびに、すべてのパラメータを実装する必要があります。この種のことは、デフォルトの の値をプロトコル関数宣言に提供できないためです。

は、プロトコルErrorPopoverRendererのので専らUIViewControllerによる使用のために意図されていない。■(またはそのサブクラス)は、次いで、上記の溶液は、非常に一般的ではありません。

我々はErrorPopoverRendererのより広範な用途を持つようにしたい場合は、我々はプロトコル拡張におけるプロトコルの使用をするかもしれない各クラス型のため特定青写真を置きます。方法presentError()のためのErrorPopoverRenderer青写真のより詳細な部分は、おそらくプロトコルに準拠する異なるクラスに対して異なって指定することができ、方法presentError()はより最小限にすることができるので、これは本当にきれいです。

は私が例から、引用:

はここ自己を使用して、その拡張子がしか配座異性はのUIViewControllerを継承する場合に限り、 行われることを示しています。 これは、が、ErrorPopoverRendererが 実際にUIViewControllerであり、UIViewControllerを拡張しないと仮定する能力を提供します。この方法では

コードは、今ではpresentError()を呼び出しますビューコントローラであることを(我々はすでに1で、やった)を知っているので、我々は青写真の実装に直接具体的なUIViewControllerのものを置くことができ、長い引数リストとして送る必要はありません。したがって

、2.私たちは、わずかに(いくつかの異なるUIViewControllerからpresentError(... lots of args ...)presentError()を呼び出す:S)コードの重複を最小限に抑えるという意味で、この特定の用途のために、より多くの「一般的な」アプローチの一種です。

extension UIViewController: ErrorPopoverRenderer { } 

実際そうUIViewControllerのすべてのインスタンスが現在のプロトコルから&プロパティメソッドにアクセスしている、UIViewControllerクラスを拡張:

3

差は、最初のことです。 これは、プロトコルを実装するクラスを拡張することを意味するものではなく、今はこのクラスのプロトコルを実装していることを意味します。通常、その拡張子にメソッド&のいくつかを実装する必要があります。

秒1で

extension ErrorPopoverRenderer where Self: UIViewController {} 

あなたが実際にメソッドにプロトコルを実装しErrorPopoverRendererUIViewControllerため&プロパティを追加します。

まずあなたが全体のプロトコルの実装を持つクラスを拡張し、2つ目には、クラスを拡張し、基本的に

が、このクラスまたはサブクラスは、プロトコルErrorPopoverRendererを実装している場合。