匹配来自 Objective-C 协议实例的 Swift 协议
Posted
技术标签:
【中文标题】匹配来自 Objective-C 协议实例的 Swift 协议【英文标题】:Matching a Swift protocol from an Objective-C Protocol instance 【发布时间】:2017-07-10 11:58:04 【问题描述】:我正在寻找一种将 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 doesn't conform to itself?. 您是否要检查meta
是否严格等同于MyProtocol
,或者是否等同于或派生自MyProtocol
?
我想测试 meta 是否兼容/符合MyProtocol
【参考方案1】:
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
不能工作。而且,尽管 Swift 可以隐式地将 @objc
协议元类型桥接到 Protocol
,但它似乎不能反过来;这就是为什么is MyProtocol.Protocol
不起作用(但即使它起作用,它也不适用于派生 协议;因为P.Protocol
类型目前只能保存值P.self
)。
如果要检查meta
是否是与MyProtocol
等效或派生自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
【讨论】:
就是这样!我没有怀疑这些功能的存在。感谢您指出这一点! 乐于帮助@yageek :)以上是关于匹配来自 Objective-C 协议实例的 Swift 协议的主要内容,如果未能解决你的问题,请参考以下文章
在我的 Swift 应用程序中使用来自 XPC 服务的 Objective-C 协议