iOS:使用 CoreData 的聊天应用程序

Posted

技术标签:

【中文标题】iOS:使用 CoreData 的聊天应用程序【英文标题】:iOS: Chat application with CoreData 【发布时间】:2014-03-05 10:35:54 【问题描述】:

我正在为 ios 开发一个聊天应用程序。该应用程序将允许用户创建聊天室并与聊天室中的成员聊天(如 IRC 聊天室)。

应用的流程是;

    用户可以加入聊天室 消息将存储在 coradata 支持的 SQLite 中 数据库 本地消息和服务器中的消息(所有 与特定用户相关的消息仅存储在他的本地数据库中) 我正在使用 NSFetchResultController 来更新和刷新聊天 桌子。收到聊天消息后,会将其存储到 DB 中,并且表格视图将加载新的聊天消息。 所有核心数据操作都在主线程中完成 获取请求的batchsize 是20,performfetch 方法是 致电viewDidLoad

问题

    收到聊天消息后,UI 会挂起一段时间(1 - iPhone 4 中为 2 秒)。 (如果我暂停执行,它表明那里 获取控制器的 [tableview endUpdate] 中发生了什么 委托) 要转到当前聊天视图中的最新聊天,用户必须 从数据库加载所有聊天记录

问题

    有没有更好的方法来处理这个要求?使用fetchresultcontroller可以吗?

    如何以分页方式加载聊天 - 比如什么 sup 或 viber - 使用fetchresultcontroller

    如果我将后台模式与多个托管对象上下文一起使用,是否会提高性能?

【问题讨论】:

【参考方案1】:
    即使使用 NSFetchedResultsController 也非常好,它就是为此类操作而设计的。 批量大小有点像分页。看看this post,第一个答案展示了如何使用限制和批量大小,如分页。 取决于您的意思,更新/保存到核心数据可以很好地在后台线程中处理(我建议这样做)。获取是另一回事,请记住 all UI changes have to be be done on the main thread.。

最好将数据变异和数据获取视为两个单独的任务,这样您就可以在进行中同时优化它们。我强烈考虑阅读this article 以了解有关此事的更多信息:

CoreData 大师 Marcus Zarra 向我展示了以下方法,该方法基于上述 Parent/Child 方法,但添加了专门用于写入磁盘的额外上下文。如前所述,冗长的写入操作可能会在短时间内阻塞主线程,从而导致 UI 冻结。这种聪明的方法将写入解耦到它自己的私有队列中,并保持 UI 像按钮一样流畅。

【讨论】:

【参考方案2】:

您需要在后台线程上执行 CoreData 的工作。有很多例子 (here's one) 可以做到这一点,但我的建议是使用 MagicalRecord,它使 CoreData 并发操作变得非常容易。

【讨论】:

学习核心数据本身将比使用包装核心数据的第三方框架走得更远。甚至 MagicalRecord 的创建者也表示最好首先学习 Core Data。创建子上下文和NSOperation 子类不是高级主题,值得学习。 无法与Core Data的高手争论:)非常真实。【参考方案3】:

所有核心数据操作都在主线程中完成

这是你的问题。只有通过NSFetchResultController 的对象访问应该在主线程上。更新NSManagedObjects 应该在后台队列上完成,同时有一个并发子NSManagedObjectContext

【讨论】:

我不太确定。插入一个新行然后获取它如何需要 1 到 2 秒?这应该足够快,可以在主线程上完成,我认为还有其他事情发生。 核心数据,尤其是NSFetchedResultsController,不仅“插入和获取”模型。它查询部分对象、监视更改、在需要模型属性值时触发故障、处理更改、保存到磁盘等等。如果你在主线程上进行更新和保存,你就不必要地阻塞了所谓的只读NSFetchedResultsController 是的,我知道它可以做到这一切,但根据我的经验,它发生在微秒内,而不是几秒内。我确实在后台线程上使用单独的上下文来处理缓慢的事情(例如:向数据库中插入 3,000 个新条目),但我大部分时间都不需要打扰。通常,更改速度足够快,可以在主线程上完成。 您的用例可能很幸运。一旦你处理复杂的关系或多个NSFetchResultControllers,(等等),即使只有几百条记录也会引起明显的打嗝。【参考方案4】:

关于你的问题 2。

您创建一个新数组 - 即 chatArray - 并从您的数据库中获取最后 20 个聊天,然后使用 chatArray 加载聊天表视图。 在 Tableview 标题上显示一个加载更多按钮,当用户到达顶部并点击该按钮时-

从 chatArray 中删除所有对象,并从您的数据库中添加最后 20 条聊天记录,然后再次重新加载您的表。继续这个过程。

我不擅长fetchresultcontroller,会做一些研究让你知道。

【讨论】:

以上是关于iOS:使用 CoreData 的聊天应用程序的主要内容,如果未能解决你的问题,请参考以下文章

在 IOS 中存储聊天消息和对话的最佳方式是啥

使用没有版本的版本更新使用 coredata 的 ios 应用程序

使用 iOS 5 和 RestKit 设置 CoreData 应用程序的正确方法是啥

如何检索由具有不正确 CoreData 架构的更新 iOS 应用程序导致的数据丢失

iOS 核心数据应用程序委托?

CoreData:升级应用程序时返回 nil 的字段