管理全局状态(无单例)

时间:2018-12-08 15:37:47

标签: ios swift

这是一个非常概念性的问题,因此,如果您需要更多详细信息,请告诉我。

对于高级摘要,我有一组视图控制器:

HomeViewController-这是应用程序中的第一个VC,并显示数据列表。

ListViewController-由HomeViewController呈现,显示与HomeViewController中描述的数据相同的列表,但呈现的略有不同。

AddViewController-由ListViewController表示,添加显示在列表中的项目。

当用户完成在AddViewController中添加项目时,我已将其编码为弹出AddViewController,并在viewDidAppear上使用ListViewController重新加载了{ {1}}以反映新项目。

现在,问题-弹出ListViewController回到ListViewController,我也想更新。现在-我可以再次使用HomeViewController,但是,为了不杀死服务器,我希望有一个系统显示“仅在需要时更新”。

显而易见的解决方案是为每个视图都配备一个单例状态管理系统。保留一些“具有hasUpdated”视图的字典,并在其中传递一个视图ID(可能是VC的哈希值),这将说明是否轮询服务器或缓存。

我已经在做iOS一段时间了,并且知道Singletons被认为是一种反模式。

另一种解决方案是在每个视图控制器上携带某种'isDirty'状态,并在需要时拦截pop动作以调用闭包……这似乎太冗长了!一个全球状态管理系统将更易于理解和阅读,但存在很多问题。

这似乎是一件很简单的事情-我想我以前从未见过这个问题,因为我只在单向应用程序上工作(即应用程序下载并显示数据,而不是用户更改数据)

有什么想法吗?

3 个答案:

答案 0 :(得分:1)

有不同的实现方法。而且,这还取决于如何将数据保留在本地缓存中。

例如,如果您使用核心数据,则可以观察到特定类型的实体的任何更改,并对相应的单元格行执行重新加载,添加/删除单元格行等等。

如果数据更简单,也许保存在数组中-我将创建一个StateController对象,它将包含Array属性并对其执行操作。您可以使用Closures或Delegate Protocol方法来与与之挂钩的任何视图控制器进行通信。

答案 1 :(得分:1)

您非常希望只有一个数据模型实例;否则,您最终可能会出现不一致的情况。

两种常见的方法是传递给每个VC的单例或单个实例(依赖项注入模式)。

Singleton方法的缺点是它会影响可测试性。由于使用Singleton的每个对象都有一个Something.shared的显式调用,因此很难模拟Something

优点是不需要修改初始化过程,甚至不需要为对象添加属性。您可以在需要时仅获取Singleton实例。

此外,单例模式强制执行以下规则:对象只能有一个 instance

使用依赖项注入,您可以实例化MockSomething,并且由于此对象传递给每个使用对象,因此这些使用者不知道他们正在处理Something的模拟子类。

缺点是,真正的DI对于UIViewController来说很棘手,因为您不能更改初始化程序签名以包括依赖项。这意味着您可能会为Something引用提供一个可选的或隐式解包的可选,您可能会喜欢,也可能不喜欢。

您确实需要根据具体情况进行评估,而不是简单地放弃使用Singleton。

您不需要模拟的模型对象可能很好。

答案 2 :(得分:0)

我认为问题减少到1个对象(模型)与N个对象(ViewController)之间的通信。

有多种方法可以实现这一目标。 iOS中最常见的解决方案是使用Notifications through the NotificationCenter。另外,您可以尝试实现类似Observation的模式,因此 Observers (ViewControllers)将请求观察在主题(模型)上的更改。