如何为iNetworkSubscriber协议实现基于对象引用相等的Equatable协议?
解决iNetworkSubscriber协议基于对象引用的Equatable实现问题
你遇到的问题核心在于Equatable协议带有Self关联类型要求,同时协议类型默认不支持引用相等判断(因为协议可以被值类型实现)。下面给你一步步的解决方案:
第一步:修改协议为类专属协议
首先,让你的iNetworkSubscriber协议继承AnyObject,这样它就只能被类类型实现,确保我们处理的都是引用类型:
protocol iNetworkSubscriber: AnyObject, Equatable { func onMessage(_ packet: NetworkPacket) }
第二步:实现基于引用相等的==运算符
现在因为协议已经限制为类专属,我们可以直接使用身份运算符===来判断两个实例是否为同一对象引用:
func ==(lhs: iNetworkSubscriber, rhs: iNetworkSubscriber) -> Bool { return lhs === rhs }
或者你也可以用泛型约束的写法(效果一致,但更符合泛型协议的最佳实践):
func ==<T: iNetworkSubscriber>(lhs: T, rhs: T) -> Bool { return lhs === rhs }
为什么之前的写法会报错?
- 协议只能用作泛型约束:因为
Equatable协议要求实现者满足Self类型的相等判断,当你直接把iNetworkSubscriber作为函数参数类型时,Swift无法确定具体的Self类型,所以报错。而让协议继承AnyObject后,协议类型的变量本质是类实例的引用,编译器可以正确处理。 - 无法使用===或ObjectIdentifier:原来的协议没有限制为类专属,Swift无法保证协议的实现者是引用类型(可能是值类型),所以不允许对协议类型直接使用引用相等运算符。继承
AnyObject后,这个限制就解除了。
这样修改后,你就能正常判断两个iNetworkSubscriber实例是否为同一对象引用了。
内容的提问来源于stack exchange,提问作者salocinx
相关产品推荐
相关产品推荐

