从Objective-C协议实例匹配Swift协议

4

我希望找到一种方法,动态匹配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。

我无法想象如何解决这个问题。我的实现中是否漏掉了什么重要的东西?


可能相关: 协议本身不符合规范?. - Martin R
你想检查 meta 是否严格等同于 MyProtocol,或者等同于或派生自 MyProtocol 吗? - Hamish
我想测试元是否与“MyProtocol”兼容/符合。 - yageek
1个回答

4

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 的协议类型,则可以使用 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
很高兴能帮助 @yageek :) - Hamish

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接