具有泛型委托的泛型类。如何区分哪个对象的委托正在执行回调?

时间:2017-07-15 04:19:48

标签: swift generics

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 {

        }
    }
}

2 个答案:

答案 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)")
        }

    }
}