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
的对象访问应该在主线程上。更新NSManagedObject
s 应该在后台队列上完成,同时有一个并发子NSManagedObjectContext
。
【讨论】:
我不太确定。插入一个新行然后获取它如何需要 1 到 2 秒?这应该足够快,可以在主线程上完成,我认为还有其他事情发生。 核心数据,尤其是NSFetchedResultsController
,不仅“插入和获取”模型。它查询部分对象、监视更改、在需要模型属性值时触发故障、处理更改、保存到磁盘等等。如果你在主线程上进行更新和保存,你就不必要地阻塞了所谓的只读NSFetchedResultsController
。
是的,我知道它可以做到这一切,但根据我的经验,它发生在微秒内,而不是几秒内。我确实在后台线程上使用单独的上下文来处理缓慢的事情(例如:向数据库中插入 3,000 个新条目),但我大部分时间都不需要打扰。通常,更改速度足够快,可以在主线程上完成。
您的用例可能很幸运。一旦你处理复杂的关系或多个NSFetchResultController
s,(等等),即使只有几百条记录也会引起明显的打嗝。【参考方案4】:
关于你的问题 2。
您创建一个新数组 - 即 chatArray - 并从您的数据库中获取最后 20 个聊天,然后使用 chatArray 加载聊天表视图。 在 Tableview 标题上显示一个加载更多按钮,当用户到达顶部并点击该按钮时-
从 chatArray 中删除所有对象,并从您的数据库中添加最后 20 条聊天记录,然后再次重新加载您的表。继续这个过程。
我不擅长fetchresultcontroller,会做一些研究让你知道。
【讨论】:
以上是关于iOS:使用 CoreData 的聊天应用程序的主要内容,如果未能解决你的问题,请参考以下文章
使用没有版本的版本更新使用 coredata 的 ios 应用程序
使用 iOS 5 和 RestKit 设置 CoreData 应用程序的正确方法是啥