ios - fetchBatchSize 和 NSFetchedResultsController 中的缓存被忽略

标签 ios swift xcode core-data nsfetchedresultscontroller

我正在使用 NSFetchedResultsController 在聊天室应用程序中显示消息。

上下文变量在 appDelegate 中分配,并在聊天室中引用该上下文。

let context = persistentContainer.viewContext

我在 viewDidLoad 中初始化 NSFRC 如下:

func initializeResultsController() {
    let request = NSFetchRequest<Message>(entityName: "Message")
    let messageSort = NSSortDescriptor(key: "dateCreated", ascending: true)

    request.sortDescriptors = [messageSort]
    request.predicate = NSPredicate(format: "chatRoomId == %@", self.chatRoomId)
    request.fetchBatchSize = 30

    fetchedResultsController = NSFetchedResultsController(fetchRequest: request, managedObjectContext: context, sectionNameKeyPath: "messageDateSectionIdentifier", cacheName: self.chatRoomId)
    fetchedResultsController.delegate = self

    do {
        try fetchedResultsController.performFetch()
    } catch {
        fatalError("Failed to initialize FetchedResultsController: \(error)")
    }
}

sectionNameKeyPath(“messageDateSectionIdentifier”)是一个派生属性,因此这些部分可以分为日历日。

我有两个问题。首先 batchSize 似乎被忽略了,其次缓存似乎对性能没有影响。消息越多,选择聊天室时的延迟时间越长。 1500 条消息大约需要 1 秒。

当我编辑方案以在控制台中显示 coreData 信息时,当 View 首次出现时多次执行 30 行的批处理请求,在一种情况下数组大小为 1500。不确定这是故障数组还是已填充大批。控制台打印输出为:

CoreData: annotation: sql connection fetch time: 0.0013s
CoreData: annotation: total fetch execution time: 0.0014s for 1454 rows.
CoreData: annotation: Bound intarray _Z_intarray0
CoreData: annotation: Bound intarray values.

此后重复多次,值为 30 行。

我尝试将 sectionNameKeyPath 简化为 dateCreated 以查看派生部分是否是问题所在,但根本没有区别。我还应该提到,与所有聊天应用程序一样,该应用程序在显示时最初会滚动到底部。

我想要的是让缓存正常工作,同时让 fetchBatchSize 正常工作,以便在用户开始向上滚动之前,最初只从 coreData 获取 30 行。现在,此方法造成的延迟对我的应用性能产生了可衡量的影响。

最佳答案

batchSize 没有被 fetchedResultsController 考虑是正确的。 NSFetchedResultsController 执行一次获取,然后跟踪上下文中的所有更改,以查看是否添加、删除、移动或更改了任何内容。如果它仅通过尊重 batchSize 获取匹配实体的一个子集,它将无法完成它的工作。

您可以通过将谓词设置为仅在特定日期后获取消息来解决此问题。为了弄清楚截止日期是什么,您可以先进行一次提取,其中 batchSize = 1 和 batchOffset = [您最初想要在 fetchedResultsController 中接收多少消息]。随着越来越多的消息进入集合,其大小将超过您的初始限制。

另请注意,集合中的每个元素都会调用 sectionNameKeyPath。因此,即使在那里做少量工作也会造成巨大的延误。不要在 sectionNameKeyPath 中创建日历或 dataFormatter - 重复使用一个。

关于ios - fetchBatchSize 和 NSFetchedResultsController 中的缓存被忽略,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50654497/

相关文章:

ios - UI未在ViewController MVVM中更新

Swift:不能在 if let 语句条件中使用数组过滤器

xcode - 在 Xcode 7.0 中获取框架相关警告

objective-c - 我需要删除启用 ARC 的项目中的所有内存管理方法吗?

ios - 如何获得默认的 iOS 红色警告颜色?

iphone - 我可以通过 testflight 分发测试而不在 iTunes Connect 上创建我的应用程序吗?

ios - 在不同的滑动 View 之间传递 UIPageViewController 中的数据

ios - 推送导航后不显示 UIImageView

iphone - 带有自定义子对象的 NSCoding

swift - 这个矩阵相邻单元格计数的解决方案有什么问题? ( swift )