Swift 4.0中[Node]类型不遵循Equatable协议的问题排查与解决
问题解析:Swift 4.1 vs 4.0中
[Node]的Equatable一致性差异及Swift 4.0解决方案 为什么Swift 4.1编译正常,Swift 4.0报错?
这是因为Swift 4.1对Objective-C类型与Swift标准库协议的桥接做了关键优化:
- 在Swift 4.0中,即便你的
Node类是Objective-C编写的NSObject子类(自带isEqual:方法),Swift也不会自动将其识别为遵循Equatable协议。而数组类型[T]要满足Equatable,必须要求元素类型T遵循Equatable,所以编译器会抛出Type '[Node]' does not conform to protocol 'Equatable'的错误。 - 在**Swift 4.1(Xcode 9.3+)**中,苹果新增了自动桥接逻辑:只要Objective-C类继承自
NSObject(或实现了isEqual:方法),Swift就会自动为其合成Equatable协议的一致性实现。这样Node就符合Equatable了,对应的数组[Node]自然也满足Equatable要求,编译就能通过。
Swift 4.0中的解决办法
有两种可行的方案,推荐第一种:
方案一:手动让Node在Swift中遵循Equatable
直接给Node添加Swift扩展,实现Equatable协议的==方法。因为Node是Objective-C的NSObject子类,我们可以直接复用它的isEqual:方法:
extension Node: Equatable { static func == (lhs: Node, rhs: Node) -> Bool { // 复用OC中的isEqual:逻辑,如果你在OC中重写过isEqual:,这里会自动调用你的自定义逻辑 return lhs.isEqual(rhs) // 如果你需要自定义Swift侧的相等判断,也可以在这里直接比较属性,比如: // return lhs.nodeID == rhs.nodeID && lhs.title == rhs.title } }
添加这个扩展后,Swift会自动为[Node]合成Equatable的一致性实现,你的TreeTVCell就能正常编译了。
方案二:直接让[Node]遵循Equatable
如果不想修改Node的协议一致性,可以直接针对[Node]数组扩展Equatable:
extension Array where Element == Node { static func == (lhs: [Node], rhs: [Node]) -> Bool { guard lhs.count == rhs.count else { return false } // 逐个元素调用isEqual:比较 for (leftItem, rightItem) in zip(lhs, rhs) { guard leftItem.isEqual(rightItem) else { return false } } return true } }
这个方案直接实现了数组的相等判断逻辑,同样能解决编译错误,但局限性在于只有[Node]数组能受益,Node本身还是不遵循Equatable。
内容的提问来源于stack exchange,提问作者hopy
相关产品推荐
相关产品推荐

