从 Objective-C 协议实例匹配 Swift 协议
Matching a Swift protocol from an Objective-C Protocol instance
我正在寻找一种方法来动态匹配具有相应 Swift 协议的 Objective-C Protocol
实例。
我在 swift 中定义了一个与 Objective-C 兼容的协议:
@objc(YHMyProtocol) protocol MyProtocol { }
我尝试在函数中执行匹配:
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
}
此函数旨在从 Objective-C 文件中调用:
if([Matcher existMatch:@protocol(YHMyProtocol)]) {
/* Do Something */
}
existMatch
函数总是 returns false。
我不知道如何解决这个问题。我在实施过程中错过了什么吗?
Protocol
是不透明的 object 类型。它在生成的 header 中定义为:
// 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
不符合MyProtocol
,所以is MyProtocol
无法工作。而且,尽管 Swift 可以隐式地将 @objc
协议元类型桥接到 Protocol
,但它似乎不能反过来;这就是为什么 is MyProtocol.Protocol
不起作用(但即使它起作用,它也不适用于 derived 协议;因为 P.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
如果您只是想检查meta
是否等同于MyProtocol
,您可以使用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
我正在寻找一种方法来动态匹配具有相应 Swift 协议的 Objective-C Protocol
实例。
我在 swift 中定义了一个与 Objective-C 兼容的协议:
@objc(YHMyProtocol) protocol MyProtocol { }
我尝试在函数中执行匹配:
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
}
此函数旨在从 Objective-C 文件中调用:
if([Matcher existMatch:@protocol(YHMyProtocol)]) {
/* Do Something */
}
existMatch
函数总是 returns false。
我不知道如何解决这个问题。我在实施过程中错过了什么吗?
Protocol
是不透明的 object 类型。它在生成的 header 中定义为:
// 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
不符合MyProtocol
,所以is MyProtocol
无法工作。而且,尽管 Swift 可以隐式地将 @objc
协议元类型桥接到 Protocol
,但它似乎不能反过来;这就是为什么 is MyProtocol.Protocol
不起作用(但即使它起作用,它也不适用于 derived 协议;因为 P.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
如果您只是想检查meta
是否等同于MyProtocol
,您可以使用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