如何将通用(关联类型需要)协议作为委托给任何控制器?

How can assing generic (associated type require) protocol as delegate to any controller?

我有一个名为 MessageType 的关联类型的协议。

protocol MessageProtocol: class {
    associatedtype MessageType

    func sendMessage(_ with: MessageType)
}

然后在controller中实现

extension MainController: MessageProtocol{

    typealias MessageType = String

    func sendMessage(_ with: MessageType) {
        // sending message
    }
}

我的目的是在其他控制器中使用协议作为委托,如下所示。

final class AnotherController {

    weak var messagerDelegate: MessageProtocol?

    ...
}

但是我得到了错误

Protocol 'MessageProtocol' can only be used as a generic constraint because it has Self or associated type requirements

有什么办法可以处理这个错误吗?

我读过 Big Nerd Ranch 的博客 post,了解这种情况。 https://www.bignerdranch.com/blog/why-associated-type-requirements-become-generic-constraints/

我了解了这种情况,但不知道如何实现?

谢谢,

我就是这样处理的。

final class AnotherController<T: MessageProtocol> where T.MessageType == String {

    weak var messagerDelegate: T?

    ...
}

如果我想以编程方式创建另一个 Controller 实例,我就是这样创建的。

let instance = AnotherController<MainController>(frame: CGRect.zero)
instance.delegate = self
...

因为 MainController

MessageProtocol 很满意

extension MainController: MessageProtocol{}

可能这不是常见的情况,但对我有用。