【问题标题】:Notifying ViewController from model(networkClient) in swift迅速从模型(networkClient)通知ViewController
【发布时间】:2019-04-07 12:33:12
【问题描述】:

我的应用中有一些复杂的网络(由于项目要求,我不使用任何第三方依赖项)。例如,在前两个请求提供结果后,我并行发送三个网络请求。我所有的网络都是在单独的模型中完成的,称为 networkClients(遵循 MVC-S 模式)并且直接从存储库调用,而不是从 ViewControllers。 但是,我需要在收到网络响应后的最后一个请求来通知我的 viewController。 我应该怎么做?我认为通知中心不是正确的解决方案,因为它会导致内存泄漏,而且我还没有找到解决此类复杂问题的正确方法。请提供一些突出的解决方案。它应该符合良好的设计模式,如 MVVM 或 MVC,不应该是一些变通方法或 hack。也许代表会工作? 我知道 rxSwift 可以解决我的问题,因为我可以在初始化 viewController 之后开始观察结果,并且在从存储库更新数据之后,我的 viewController 也会收到通知......

【问题讨论】:

  • 你能澄清一下“最后的请求”吗?你是指最后一个完成的吗?
  • 我认为通知中心非常适合这种情况。模式是用来解决问题的,而不是引起问题的。
  • @danh 是的,最后一个请求完成并获得了一些数据(这个请求也被多次调用,直到满足某个条件,然后 API 固定停止)。但结果应该每次都发送到 viewController。
  • @meaning-matters 我使用 dispatchGroup 但用于其他目的。例如:它可以帮助我确定何时应该发送我的最终请求。它真的很好用。但是,我应该如何在 DispatchGroup 触发通知后通知我的 ViewController?

标签: ios swift model-view-controller nsnotificationcenter uiapplicationdelegate


【解决方案1】:

正确的设计不会让 VC 直接观察网络客户端。这些网络操作应该是组装一个模型的一部分,这才是 VC 真正关心的。让 VC 观察那个奇异模型。

它可以使用一种众所周知的对象间松散耦合通信模式来进行这种观察。 OP 正确地提到了代表。通知中心和 KVO 是其他的。关于使用哪个以及如何实现的 SO 有很多讨论。 (我会选择NSNotificationCenter 作为一个简单而理性的开始)。

所以操作顺序是这样的:

  1. 分配模型
  2. 启动网络请求并设置这些请求完成(可能是完成块)以使用其响应更新该模型。 (模型可以发起请求,这是一种合理的做法)。
  3. 创建在初始化时设置模型观察的视图控制器(可能在viewWillAppear 或更高版本中)

>1 个请求同时进行的事实如何?上面的一位评论者正确地指出,GCD 提供了一种将这些异步操作分组为一个的方法。但是您可以直接自己做:模型决定何时完全构建。每个请求的完成代码会将模型中的某些条件更改为“就绪”状态。每个请求完成都可以检查是否满足所有的就绪条件,然后才发布“就绪”通知供观察者查看。

另一个琐碎的问题:如果这些请求都运行得非常非常快怎么办?也许有一些缓存响应很早就准备好了,在 VC 有机会设置观察之前使模型“准备好”?在 VC 中直接处理这个问题:在观察模型之前,检查它是否已经准备好并运行在通知上运行的相同更新代码。

【讨论】:

  • 这个解释真的很清楚。真的很感谢你最后两段。也许我没有完美地解释自己,但这就是我所说的来自模型的网络请求的意思。模型(称为存储库)在另一个请求处理完成块后启动所需的网络请求。该模型(存储库)使用另一个模型(网络客户端),其中包含创建请求所需的所有代码并执行它。之后(网络客户端)向存储库提供完成块,我的存储库可以启动通知,是吗? :) 应该在 VC 中观察到该通知,是吗?
  • @ViktorVostrikov - 我想我理解你,是的。听起来存储库一旦建成,就包含了 VC 需要知道的一切。因此,将其称为您的 VC 模型是合理的。让该存储库检查就绪条件并让它通知世界它已准备好。我可能不会将“模型”一词应用于网络客户端。
  • 是的,但是需要更详细的说明:这个存储库是单例的,因为它有一些信息,另一个 VC 也需要这些信息并且共享逻辑。就像第一个 VC 做 1/3 的工作,第二个 VC 另一个 1/3 和第三个做最后的部分。与整个应用程序功能相关的所有数据都存储在存储库中。我发现在这种情况下,单例模式是不错的主意。是的,网络客户端可能被称为助手
  • @ViktorVostrikov,我同意。
  • 真的非常感谢...这些信息是无价的!你应该写一些博客或者中篇文章! 10/10 质量!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-03-22
  • 1970-01-01
  • 1970-01-01
  • 2017-12-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多