Swift代表一个泛型类 [英] Swift delegate for a generic class

查看:90
本文介绍了Swift代表一个泛型类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个类需要在其中一个属性发生变化时调出。下面是委托的简化类和协议:

I have a class that needs to call out to a delegate when one of its properties changes. Here are the simplified class and protocol for the delegate:

protocol MyClassDelegate: class {
    func valueChanged(myClass: MyClass)
}

class MyClass {

    weak var delegate: MyClassDelegate?

    var currentValue: Int {
        didSet {
            if let actualDelegate = delegate {
                actualDelegate.valueChanged(self)
            }
        }
    }

    init(initialValue: Int) {
        currentValue = initialValue
    }
}

这一切都很好。但是,我想让这个类变得通用。所以,我试过这个:

This all works just fine. But, I want to make this class generic. So, I tried this:

protocol MyClassDelegate: class {
    func valueChanged(genericClass: MyClass)
}

class MyClass<T> {

    weak var delegate: MyClassDelegate?

    var currentValue: T {
        didSet {
            if let actualDelegate = delegate {
                actualDelegate.valueChanged(self)
            }
        }
    }

    init(initialValue: T) {
        currentValue = initialValue
    }
}

这会引发两个编译器错误。首先,协议中声明 valueChanged 的行给出:引用泛型类型'MyClass'需要参数在< ...> 。其次,在 didSet 监视器中调用 valueChanged 时抛出:'MyClassDelegate'没有一个名为'valueChanged'的成员

This throws two compiler errors. First, the line declaring valueChanged in the protocol gives: Reference to generic type 'MyClass' requires arguments in <...>. Second, the call to valueChanged in the didSet watcher throws: 'MyClassDelegate' does not have a member named 'valueChanged'.

我认为使用 typealias 问题:

I thought using a typealias would solve the problem:

protocol MyClassDelegate: class {
    typealias MyClassValueType
    func valueChanged(genericClass: MyClass<MyClassValueType>)
}

class MyClass<T> {

    weak var delegate: MyClassDelegate?

    var currentValue: T {
        didSet {
            if let actualDelegate = delegate {
                actualDelegate.valueChanged(self)
            }
        }
    }

    init(initialValue: T) {
        currentValue = initialValue
    }
}

我似乎在正确的道路上,但我仍然有两个编译器错误。上面的第二个错误仍然存​​在,并且在声明 MyClass 委托属性的行上有一个新错误: Protocol'MyClassDelegate'只能用作通用约束,因为它具有自我或相关类型要求

I seem to be on the right path, but I still have two compiler errors. The second error from above remains, as well as a new one on the line declaring the delegate property of MyClass: Protocol 'MyClassDelegate' can only be used as a generic constraint because it has Self or associated type requirements.

任何方式来实现这一目标?

Is there any way to accomplish this?

推荐答案

在没有更多信息的情况下,很难知道最佳解决方案是什么。一个可能的解决方案是将协议声明更改为:

It is hard to know what the best solution is to your problem without having more information, but one possible solution is to change your protocol declaration to this:

protocol MyClassDelegate: class {
    func valueChanged<T>(genericClass: MyClass<T>)
}

不需要 typealias 在协议中,并且应该解决你收到的错误信息。

That removes the need for a typealias in the protocol and should resolve the error messages that you've been getting.

米不知道这是否是最好的解决方案是因为我不知道如何或在哪里 va lueChanged 函数被调用,所以我不知道是否可以向该函数添加一个通用参数。如果此解决方案无效,请发表评论。

Part of the reason why I'm not sure if this is the best solution for you is because I don't know how or where the valueChanged function is called, and so I don't know if it is practical to add a generic parameter to that function. If this solution doesn't work, post a comment.

这篇关于Swift代表一个泛型类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆