[英]Matching a Swift protocol from an Objective-C Protocol instance
我正在寻找一种方法来动态匹配Objective-C Protocol
实例与相应的Swift协议。
我在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
函数始终返回false。
我无法弄清楚如何解决这个问题。 我是否遗漏了实施中的内容?
Protocol
是一种不透明的对象类型。 它在生成的头文件中定义为:
// 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
无法正常工作。 而且,虽然斯威夫特可以隐桥@objc
协议元类型,以Protocol
,看来,它不能做反向; 这就是为什么is MyProtocol.Protocol
不起作用(但即使它确实如此,它也不适用于派生协议;因为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
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.