在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出于某种原因禁用了此“功能”。 具有庞大的协议会违反接口隔离原则,并使它们无法读取。 表视图是我作为开发人员生活的重要部分,但我仍然不记得UITableViewDelegateUITableViewDataSource协议中定义的内容,因为列表太长了。

那么……为什么我们不对每个单向动作都使用观察者模式呢? 我们可以提供具有更大灵活性的相同功能,并且还可以清除大型委托协议中的大多数方法。

我们有一个设置页面,其中包含主题选择。 每当主题更改时,我们都希望更新主屏幕。

解决方案1:使用委派

此解决方案有效,但是否足够灵活? 如果我们有5个选项卡要与此主题更改进行更新,会发生什么情况?

解决方案2:使用NotificationCenter

现在,我们支持一对多通信,但是我们将线路数量增加了一倍,对吗? 这是NotificationCenter的主要问题。 它功能强大,但不是很方便。

解决方案3:使用频道

什么是频道?

没什么新鲜的。 Channel是观察者模式的实现,它提供了比NotificationCenter更好的API。

  • 创建一个频道:
 枚举消息{ 
案例themeDidChange(Theme)
}让channel = Channel ()
  • 订阅它:
  channel.subscribe(self){消息在 
//在此处处理消息。
}
  • 广播一条消息:
  channel.broadcast(.themeDidChange(.light)) 

因此,使用渠道,我们的解决方案如下所示:

  • 通过调整单向通信的通道和双向通信的委派,我们可以使代码中的数据流标准化。
  • 我们终于可以停止使用NotificationCenter
  • 通道实现少于100行代码,现在是Lightning框架的一部分。

感谢您一直滚动!

您的意见很重要! 请让我知道您的想法,并帮助您推广。 ❤️👏