我知道问题发布已经有一段时间了,但我希望我的回答能有所帮助。
==
TLDR -您提供自定义比较方法,==
调用它,并在需要时覆盖自定义比较方法,而不是尝试覆盖。
所以你说
所有的类都只会在 Swift 中使用,所以我不想涉及NSObject
协议NSCopying
。
但是如果你要子类,NSObject
你将如何编写你的自定义比较方法?你会覆盖isEqual(Any?)
,对吧?如果你试图在你的子类中遵守Equatable
协议,编译器会抱怨“冗余的协议一致性Equatable
”,因为NSObject
已经符合Equatable
.
现在这给了我们一些关于如何NSObject
处理这个问题的提示——它提供了一个自定义的比较方法isEqual(Any?)
,在内部调用它==
,如果需要,它的子类可以覆盖它。您可以在自己的基类中执行相同的操作。
事不宜迟,让我们做一些实验(在 Swift 4 中)。定义一些类
class Grandpa: Equatable {
var x = 0
static func ==(lhs: Grandpa, rhs: Grandpa) -> Bool {
return lhs.isEqual(to: rhs)
}
func isEqual(to object: Any?) -> Bool {
guard object != nil && type(of: object!) == Grandpa.self else {
return false
}
let value = object as! Grandpa
return x == value.x
}
}
class Father: Grandpa {
var y = 0
override func isEqual(to object: Any?) -> Bool {
guard object != nil && type(of: object!) == Father.self else {
return false
}
let value = object as! Father
return x == value.x && y == value.y
}
}
class Son: Father {
var z = 0
override func isEqual(to object: Any?) -> Bool {
guard object != nil && type(of: object!) == Son.self else {
return false
}
let value = object as! Son
return x == value.x && y == value.y && z == value.z
}
}
并写一些测试代码
let grandpa1 = Grandpa()
let grandpa2 = Grandpa()
let grandpa3: Grandpa? = nil
let grandpa4: Grandpa? = nil
let father1 = Father()
let father2 = Father()
let father3 = Father()
father3.y = 1
let son1 = Son()
let son2 = Son()
let son3 = Son()
son3.z = 1
print("grandpa1 == grandpa2: \(grandpa1 == grandpa2)")
print("grandpa1 == grandpa3: \(grandpa1 == grandpa3)")
print("grandpa3 == grandpa4: \(grandpa3 == grandpa4)")
print("grandpa1 == father1: \(grandpa1 == father1)")
print("father1 == father2: \(father1 == father2)")
print("father1 == father3: \(father1 == father3)")
print("son1 == son2: \(son1 == son2)")
print("son1 == son3: \(son1 == son3)")
运行它,你应该得到
grandpa1 == grandpa2: true
grandpa1 == grandpa3: false
grandpa3 == grandpa4: true
grandpa1 == father1: false
father1 == father2: true
father1 == father3: false
son1 == son2: true
son1 == son3: false