在 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
。显然这行不通,因为
Message
不可散列,并且
- 注册需要一个类型作为参数,这是不可能的,因为这不是通用的。
我目前的解决方案是将 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)
我正在尝试在 Swift 中实现一种发布-订阅。在我当前的情况下,有些消息仅发送给接收者,而其他消息则另外需要触发回调。现在,我定义了一个 enum
来保存不同的消息,例如
enum Message
{
case Foo
case Bar(() -> Void)
}
即Foo
是没有回调的消息,Bar
需要回调。接收方可以对接收到的消息应用开关并做出决定。此外,接收者只能订阅消息类型的一个子集。
对于注册,有一个代理保存消息类型和相关接收者的字典。 IMO 实施这个理想的解决方案是:
class Broker
{
var subscribers = Dictionary<Message, Array<Receiver>>()
}
其中 Receiver
是协议,Message
是上面定义的 enum
。显然这行不通,因为
Message
不可散列,并且- 注册需要一个类型作为参数,这是不可能的,因为这不是通用的。
我目前的解决方案是将 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)