2017-01-09 12 views
1

質問はSwift3を参照しています。私はそれから継承プロトコルと複数の種類がありNSObject <Protocol>にプロトコルをキャストして制約付き拡張インターフェイスにアクセスする方法は?

someObject as (Type & Protocol) 

: は、バージョン4以来、あなたは、このようType<Protocol>にオブジェクトを最後にキャストすることができます。そのプロトコルについて

A, B, C, D: CKEntity (pseudocode) 

IオブジェクトはNSObjectのから継承する場合があります

拡張である:複数のケースのperferctly

extension CKEntity where Self : NSObject { 

static func method() { 
    ... 
} 

ワーク。

そして、私はCKEntityを実装するClass(Type)をとる関数を持っています。

NSObjectでもあればケースに合っているかどうかチェックする必要があります。 そうであれば、適切な関数を呼び出します。私が達成しようとしているものの

プロトタイプ:

func validateSync(ofType type: CKEntity.Type) { 
    let a = (type as NSObject.Type & CKEntity.Type).self 

    a.method() // Compilation error: Type 'Any' has no member 'method' 
} 

動作しません。

質問です:私は拡張機能の制約を満たすためにNSObject.Type(インスタンスではなく)にタイプ(Protocol.Type)をキャストするにはどうすればよい


シナリオ(要約):AはAをにキャストする必要B

  • かもしれB

  • あるA用

    1. 拡張:Bと制限されたA & Bインターフェイスに到達します。

  • 答えて

    0

    解決策が見つかりました。

    ところは、NSObjectのを拡張することになると、それは(あなたが後者を拡張しようとしている場合でも)NSObjectの自体ではなく、NSObjectProtocolを拡張するに頼ることが好ましいということです。

    なぜなら、NSObject自体はプロトコルではなく、Swiftコンポジットプロトコルチェックに困難をもたらすからです。 NSObjectProtocolは、一方で、NSObject由来のオブジェクトによって自然に継承され、鍵であるプロトコルです。

    したがって、我々は可能な場合は、複数のプロトコルにタイプをダウンキャストする事をリファクタリングすべきところ、それはだ(と、それはNSObjectのことだ場合には、可能です)。

    extension NSObjectProtocol where Self : CKEntity { 
        static func method() { 
         // ... 
        } 
    } 
    

    とチェックは次のとおりです:

    拡張は以下のように変更された

    if let extendedType = type as? NSObjectProtocol & CKEntity.Type { 
        extendedType.self.method() 
    } 
    

    そして、それは働きます!あなたはKVCインターフェイスを取得するには、このようなあなたのオブジェクトをキャストする必要がありますので、1は全体つまずくことができ

    欠点は、NSObjectProtocolがKVCメソッドが含まれていないものであろう:

    extension NSObjectProtocol where Self : CKEntity { 
    
        static var staticVar : String { 
         return (Self.self as! NSObject.Type).className() 
        } 
    
    
        var publicVar : String! { 
         return (self as! NSObject).value(forKey: "Key") as! String 
        } 
    } 
    
    関連する問題