MyClass是一个具有泛型委托的泛型类。 AClass包含两个MyClass的iVar实例,并且还实现了MyClassDelegate。
在AClass实现MyClassDelegate的地方,如何区分哪个对象正在调用接口?对于非泛型类,==是可以接受的。
请参阅此代码段底部的注释和错误消息。
protocol MyClassDelegate: class {
func myClass<T>(_ myClass: MyClass<T>, valueDidChange value: T)
}
class MyClass<T: Comparable> {
private var _value: T
var value: T {
set {
delegate?.myClass(self, valueDidChange: newValue)
}
get {
return _value
}
}
var delegate: MyClassDelegate?
init(value: T) {
_value = value
}
}
class AClass {
private var thing1 = MyClass(value: Int(10))
private var thing2 = MyClass(value: Int(100))
private var thing3 = MyClass(value: TimeInterval(10))
private var thing4 = MyClass(value: TimeInterval(100))
init() {
thing1.delegate = self
thing2.delegate = self
thing3.delegate = self
thing4.delegate = self
}
}
extension AClass: MyClassDelegate {
func myClass<T>(_ myClass: MyClass<T>, valueDidChange value: T) {
// This fails to complile
// Binary operator '==' cannot be applied to operands of type 'MyClass<T>' and 'MyClass<Int>'
if myClass == thing1 {
}
// Binary operator '==' cannot be applied to operands of type 'MyClass<T>' and 'MyClass<TimeInterval>' (aka 'MyClass<Double>')
else if myClass == thing3 {
}
}
}
答案 0 :(得分:0)
将协议方法签名T
中的func myClass<T>(...)
类型限制为Comparable
。由于您仅将其限制在该协议的一个特定扩展名中,因此AClass
中的方法可以任何类T
,而不只是Comparable
个。
答案 1 :(得分:0)
我尝试过但尝试过但无法以可以比较来电者的方式配置通用委托。
我从NRitH读到了答案,但无法让编译器接受语法。也许有办法做到这一点,但我走了一条不同的路线,取得了成功。
我放弃了协议/委托技术,最终使用了一个回调闭包。我没有在MyClass中定义委托并在AClass中实现该委托,而是在MyClass中定义了一个回调闭包,在AClass中实现了如下所示:
class MyClass<T: Comparable>: Equatable {
var valueChanged: ((_ clazz: MyClass) -> Void)?
private var _value: T
var value: T {
set {
_value = newValue
valueChanged?(self)
}
get {
return _value
}
}
init(value: T) {
_value = value
}
static public func ==(lhs: MyClass<T>, rhs: MyClass<T>) -> Bool {
return lhs.value == rhs.value
}
}
class AClass {
fileprivate var thing1: MyClass<Int> = MyClass(value: 10)
fileprivate var thing2: MyClass<Int> = MyClass(value: 100)
fileprivate var thing3: MyClass<TimeInterval> = MyClass(value: 10)
fileprivate var thing4: MyClass<TimeInterval> = MyClass(value: 100)
init() {
thing1.valueChanged = { (thing) in
// You can compare here, but you already know which object is callling back
if thing == self.thing1 {
}
}
thing2.valueChanged = { (thing) in
print("Thing2 changed: \(thing.value)")
}
}
}