在 Swift wrt 消息类型中注册接收者对象

Register receiver objects in Swift wrt message type

我正在尝试在 Swift 中实现一种发布-订阅。在我当前的情况下,有些消息仅发送给接收者,而其他消息则另外需要触发回调。现在,我定义了一个 enum 来保存不同的消息,例如

enum Message
{
    case Foo
    case Bar(() -> Void)
}

Foo是没有回调的消息,Bar需要回调。接收方可以对接收到的消息应用开关并做出决定。此外,接收者只能订阅消息类型的一个子集。

对于注册,有一个代理保存消息类型和相关接收者的字典。 IMO 实施这个理想的解决方案是:

class Broker
{
    var subscribers = Dictionary<Message, Array<Receiver>>()
}

其中 Receiver 是协议,Message 是上面定义的 enum。显然这行不通,因为

  1. Message 不可散列,并且
  2. 注册需要一个类型作为参数,这是不可能的,因为这不是通用的。

我目前的解决方案是将 enum 扩展为:

func hash() -> String
{
    switch (self)
    {
        case Foo : return "Foo"
        case Bar(_) : return "Bar"
    }
}

并将代理中的字典替换为:

var subscribers = Dictionary<String, Array<Receiver>>()

这行得通,但现在注册需要一个消息实例才能获取哈希值,例如

broker.subscribe(receiver: self, message: Message.Bar({}).hash())

这感觉很尴尬 - 至少对我来说是这样。我认为虽然这没有错,但似乎不是最佳解决方案。

所以,问题是:订阅具有不同可接收消息类型的多个接收者的最佳方式是什么,可能不会丢失 enum

试试这样的东西:

enum Message
{
    case Foo
    case Bar(() -> Void)

    static let FooType = "Foo"
    static let BarType = "Bar"

    func hash() -> String {
        switch self {
        case Foo:       return Message.FooType
        case Bar(_):    return Message.BarType
        }
    }
}

broker.subscribe(receiver: self, message: Message.BarType)