在Swift中使用通道进行数据流📻
最初发表在 Swift Post上 。
Apple框架大量使用委托和观察者模式(NotificationCenter)来传递信息。 尽管这些模式没有错,但实际的实现始终对我来说有点矛盾。
首先让我们看一下这些模式的基本特征:
- 委派:支持一对一的双向通讯。
- 观察者 :支持一对多,单向通信。
让我们看一些UITableViewDelegate
方法。
可选的func tableView(_ tableView:UITableView,heightForRowAt indexPath:IndexPath)-> CGFloat
-
UITableView
:发件人 -
UITableViewDelegate
(主要是UIViewController
) :接收器
此方法是一对一双向通信的一个很好的例子。
由于表格视图要求控制器返回高度,因此通讯是双向的,不能一对多。 (否则,我们将无法决定应使用哪个返回的高度值。)
但是,以下方法不返回任何内容。
可选的func tableView(_ tableView:UITableView,didSelectRowAt indexPath:IndexPath)
在此,发送方仅通知接收方。 因此,通信是单向的,可以是一对一或一对多。
在这种情况下,授权是一个不错的选择吗?
–也许…如果我们需要通知多个组件会怎样?
–我们不能。如果我们不在乎行选择,而是想自己提供行高怎么办? 我们还需要提供空的实现吗?
–如果这是一个纯Swift协议, 是的 ,我们将需要为每个我们不关心的委托方法准备空的实现,这很烦人。 由于UITableViewDelegate
继承自Objective-C,因此为了向后兼容,我们可以将方法标记为可选。 但是Swift出于某种原因禁用了此“功能”。 具有庞大的协议会违反接口隔离原则,并使它们无法读取。 表视图是我作为开发人员生活的重要部分,但我仍然不记得UITableViewDelegate
和UITableViewDataSource
协议中定义的内容,因为列表太长了。
那么……为什么我们不对每个单向动作都使用观察者模式呢? 我们可以提供具有更大灵活性的相同功能,并且还可以清除大型委托协议中的大多数方法。
我们有一个设置页面,其中包含主题选择。 每当主题更改时,我们都希望更新主屏幕。
解决方案1:使用委派
此解决方案有效,但是否足够灵活? 如果我们有5个选项卡要与此主题更改进行更新,会发生什么情况?
解决方案2:使用NotificationCenter
现在,我们支持一对多通信,但是我们将线路数量增加了一倍,对吗? 这是NotificationCenter
的主要问题。 它功能强大,但不是很方便。
解决方案3:使用频道
什么是频道?
没什么新鲜的。 Channel是观察者模式的实现,它提供了比NotificationCenter
更好的API。
- 创建一个频道:
枚举消息{
案例themeDidChange(Theme)
}让channel = Channel ()
- 订阅它:
channel.subscribe(self){消息在
//在此处处理消息。
}
- 广播一条消息:
channel.broadcast(.themeDidChange(.light))
因此,使用渠道,我们的解决方案如下所示:
- 通过调整单向通信的通道和双向通信的委派,我们可以使代码中的数据流标准化。
- 我们终于可以停止使用
NotificationCenter
。 - 通道实现少于100行代码,现在是Lightning框架的一部分。
感谢您一直滚动!
您的意见很重要! 请让我知道您的想法,并帮助您推广。 ❤️👏