2017-07-10 1 views
3

Objective-C Protocolインスタンスと対応するSwiftプロトコルを動的に照合する方法を探しています。Objective-CプロトコルインスタンスからSwiftプロトコルを照合する

@objc(YHMyProtocol) protocol MyProtocol { } 

Iの関数で、一致を実行しよう:

public func existMatch(_ meta: Protocol) -> Bool { 
    // Not working 
    if meta is MyProtocol { 
     return true 
    } 

    // Not working also 
    if meta is MyProtocol.Protocol { 
     return true 
    } 

    return false 
} 

この関数は、であることが意図されている

Iは、Objective-Cのと互換性があり迅速で定義されたプロトコルを有しますObjective-Cファイルから呼び出されます。

if([Matcher existMatch:@protocol(YHMyProtocol)]) { 
    /* Do Something */ 
} 

existMatch関数は常にre偽になります。

私はこれを解決する方法を理解できません。私は実装で何かを忘れましたか?

+0

おそらく関連:[プロトコル自体に準拠していません?] (https://stackoverflow.com/questions/33112559/protocol-doesnt-conform-to-itself)。 –

+0

'meta'が厳密に' MyProtocol'に相当するのか、それとも 'MyProtocol'から派生しているのか確認しますか? – Hamish

+0

私はmetaが互換性があるか/ MyProtocolに準拠しているかどうかテストしたいと思っています – yageek

答えて

4

は、不透明なオブジェクトタイプです。それはMyProtocolに準拠していないので、is MyProtocolが動作しないことができる

// All methods of class Protocol are unavailable. 
// Use the functions in objc/runtime.h instead. 

OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0, 2.0) 
@interface Protocol : NSObject 
@end 

:それは次のように生成されたヘッダで定義されています。また、Swiftは暗黙的に@objcプロトコルのメタタイプをProtocolに橋渡しすることができますが、逆を行うことはできません。これはis MyProtocol.Protocolが機能しない理由です(たとえそれがあったとしても、タイプは現在P.selfの値しか保持できないため、プロトコルを使用しても機能しません)。

あなたはmetaと等価であるプロトコルタイプである、またはから派生し、MyProtocolことを確認したい場合は、あなたがobj-Cのランタイム関数protocol_conformsToProtocol使用することができます:あなただけたい場合

@objc(YHMyProtocol) protocol MyProtocol { } 
@objc protocol DerviedMyProtocol : MyProtocol {} 

@objc class Matcher : NSObject { 
    @objc public class func existMatch(_ meta: Protocol) -> Bool { 
     return protocol_conformsToProtocol(meta, MyProtocol.self) 
    } 
} 

// the following Swift protocol types get implicitly bridged to Protocol instances 
// when calling from Obj-C, @protocol gives you an equivalent Protocol instance. 
print(Matcher.existMatch(MyProtocol.self)) // true 
print(Matcher.existMatch(DerviedMyProtocol.self)) // true 

metaMyProtocolと等価であることを確認するために、あなたはprotocol_isEqualを使用することができます。

@objc class Matcher : NSObject { 
    @objc public class func existMatch(_ meta: Protocol) -> Bool { 
     return protocol_isEqual(meta, MyProtocol.self) 
    } 
} 

print(Matcher.existMatch(MyProtocol.self)) // true 
print(Matcher.existMatch(DerviedMyProtocol.self)) // false 
+0

それです!私はそれらの機能の存在を疑っていませんでした。これを指摘してくれてありがとう! – yageek

+0

@ yageekに協力していただきありがとうございます:) – Hamish

関連する問題