【问题标题】:iOS: Design pattern for populating asynchronously fetched dataiOS:用于填充异步获取数据的设计模式
【发布时间】:2014-02-25 06:27:29
【问题描述】:

我正在开发一个从 Web 获取数据并将其显示给用户的应用程序。假设数据是一家餐馆的评论,一个评论显示在一个视图上。用户可以向左或向右滑动以进入上一个/下一个评论。数据是异步获取的(每个评论一个线程)。

这是问题陈述 - 假设已获取 5 条评论,并且用户当前正在查看第 3 条评论。现在,获取了第 6 条评论,我想将其作为第 4 条评论显示给用户(因为第 6 条评论的发布日期比第 5 条评论更近)。我的模型类应该如何通知视图控制器?

我已经考虑了一些选项 -

  1. 向视图控制器提供一个数组,然后发送 NSNotifications 关于要插入到数组之间特定索引处的新项目
  2. 使用 NSFetchedResultsController(这有点棘手,因为我没有将它与表视图控制器一起使用)
  3. 视图控制器总是要求显示下一条评论(来自模型)并且没有一系列评论

在这种情况下是否采用了任何既定的设计模式?欢迎提出除上述 3 项以外的其他建议!

【问题讨论】:

  • 这不是一个很好的问题描述来询问设计模式。您可以应用已知的 MVC 变体和“延迟加载表视图”,以及异步编程的常见做法。您声明的要求也不清楚:“现在,第 6 条评论已获取,我想将其作为第 4 条评论显示给用户。我的模型类应如何通知视图控制器?” 嗯? “我”是谁?从字面上看,如果您希望将第 6 条评论放在位置 4,那么只需将其插入到该位置的数组中,然后“更新”表格视图。不过,我不认为你有这个想法,不是吗?
  • 我就是我自己,开发者。我已经明确提到过,我不是显示表格视图,而是显示一个用户可以向右或向左滑动以查看下一个项目的视图(类似于照片应用程序)。

标签: ios design-patterns asynchronous nsnotifications nsfetchedresultscontroller


【解决方案1】:

只需使用NSFetchedResultsController。使用NSIndexPaths 时,只需忽略section。它基本上是一个带有免费通知的美化 NSArray

我认为我会这样做:

  • 确保您的NSFetchedResultsControllerNSFetchRequest 按发布日期排序。
  • 处理NSFetchedResultsControllerDelegate 方法。
  • NSFetchedResultsController 更新时,保存当前对象,重新加载集合视图,然后滚动到保存的对象,没有任何动画。这对用户来说就像当前页面没有发生任何事情一样。

【讨论】:

  • 我这样做是为了我的需要。但是,我从 2007 年开始就熟悉 Core 数据。@Akshay,如果你愿意,这是最好的方法,但是当你找到你的第一个版本和下一个版本时,你可能会遇到一些成长的痛苦。模型需要不同的东西。
  • 谢谢!我最终在我的问题中选择了选项#3。视图控制器很笨,总是要求显示下一个评论。该模型管理所有排序。这样一来,只有模型有“棘手”的代码,而控制器完全不知道。
【解决方案2】:

虽然对于每个编程问题都没有完美的设计模式,但我能想到的与您的问题最接近的是命令模式和观察者模式的组合。

https://en.wikipedia.org/wiki/Command_pattern

观察者模式用于 NSNotification 中心。

虽然不清楚您为什么要跳过评论,但您可以有两个数组在获取时存储它们。第一个包含您获取的所有评论。第二个包含所有显示的评论。

然后就可以拿到fetched数组中的最后一条review,就好像它是一个栈一样。这样,您始终会将最后一个加载的内容显示给用户。

【讨论】:

    【解决方案3】:

    我很困惑为什么显示顺序与真实顺序不同,即为什么第 6 次评论出现在第 5 次之前,但您询问了模式以提供帮助。

    除了在其他答案和 cmets 中的 MVC 和观察者之外,我建议使用带有 virtual proxy 的延迟加载。获取评论后,您可以只显示他们的代理(例如,使用“正在加载...”消息,直到他们完全在内存中)。

    在此处查看更多信息:http://en.wikipedia.org/wiki/Proxy_pattern

    【讨论】:

    • 奇怪的是他不想显示加载,他只想先显示任何加载。这就是我提出不同建议的原因。但是,如果他没有这个要求,我认为你的建议会更合适。
    • 感谢您的帮助。真实顺序与显示顺序不同的原因是 - a)我不希望用户等到所有评论都被获取 b)在这种情况下,新评论更重要,应该尽快显示被提取
    • 设计模式是对经常出现的问题的解决方案。您描述问题的方式非常独特,但也许其他人会有想法。
    • 这就是我问的原因 - “在这种情况下是否有任何既定的设计模式被采用?”答案可以是“否”。 :-)
    【解决方案4】:

    我建议使用观察模式来通知您的控制器已获取的新数据。接收到信号时,您的视图控制器可以更新其“餐厅评论”数组(通过添加旧的并根据您的风格的某种描述重新排序或直接查询 DAO)。 假设您正在从 Internet 获取数据并使用结果填充 CoreData 实体。获得下载数据后,您可以填充核心数据“审查”实体。 为了“监听”核心数据发生的变化,您的控制器应该在 viewDidLoad 主体中将自己注册为 NSManagedObjectContextDidSaveNotification 的观察者。

    [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(updateInfo:) name:NSManagedObjectContextDidSaveNotification object:nil];

    然后在您的 updateInfo 中,您可以获取更改

    - (void) updateInfo:(NSNotification *)notification { self.reviews = [self.managedObjectContext performRequest:myFetchRequest error:nil]; }

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-08-01
      • 1970-01-01
      • 1970-01-01
      • 2018-10-16
      • 2022-01-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多