【问题标题】:Solution to NSFetchResultsController memory handlingNSFetchResultsController 内存处理的解决方案
【发布时间】:2015-12-13 03:09:15
【问题描述】:

最近我正在开发一个允许一次创建和浏览大量数据的应用程序。 在此应用程序中,可以在单个时间点从NSFetchedResultsControllercollectionView 中查看 2,000 多个对象。

在测试这个场景时,很快就发现并验证了NSFetchedResultsController 在访问批处理索引时没有最佳地将NSManagedObjects 分页进出内存。

由于从NSFetchedResultsController 访问索引并且加载了更多NSManagedObjects,NSFetchedResultsController 似乎会将先前加载的NSManagedObjects 保留在内存中,而不是根据访问的索引集将它们分页进出内存使用fetchRequest 中设置的fetchBatchSize。为了进一步解释这一点,如果 fetchBatchSize 设置为 45,并且现在加载了索引 1,000,则 NSFetchedResultsController 似乎保留了在索引 1,000 之前通过索引访问加载的所有内容的内存,而这些内容是通过索引访问而不是错误的。

如果在父上下文中调用managedObjectContext.reset(),内存会被正确释放,直到通过索引访问再次加载对象。 fetchBatchSize 似乎只能阻止一次加载所有数据。访问索引时,NSFetchedResultsController 似乎会加载新批次,同时保留先前加载的批次。

我目前的想法正在引导我创建自己的分页,其中我将有多个 fetchResultsControllersfetchBatchSizes 和 fetchLimits... 这似乎比它应该复杂得多。这将创建一种手动方式将数据从内存中分页出来,从而允许正确的内存管理。

我的问题是是否有更好的方法来解决这个问题?我本质上想在使用 CoreData 时对类似于 Apple 的照片应用程序的无限对象进行分页(它们的性能让我大吃一惊)。

注意:关于这个确切问题的帖子有很多,指出人们必须制定手动解决方案来改进内存管理(例如:link#1link#2)。我不是在寻找“你忘了这个”或“你可能做错了”的答案。我可以毫无疑问地验证,我正确地使用了记录在案的 API。我正在寻找一种有助于更好地管理NSFetchedResultsController 内存的解决方案。设置fetchBatchSize 是一个临时解决方案,直到用户加载大量索引导致内存警告被触发并且我重置managedObjectContext。之前提到过,是的,我已经测试过设置和不设置 NSFetchedResultsController 缓存并相应地重置.... -如此。

【问题讨论】:

  • fetchBatch?你的意思是fetchBatchSize
  • 是的,我没有复制/粘贴确切的函数名称,只是简单介绍了总体思路/概念
  • 您是否考虑过使用 refreshObject:object mergeChanges:NO 手动故障排除不需要的对象?
  • 是的,我开始走这条路,并意识到它比什么都烦人。在尝试适当地对对象进行故障处理和取消故障处理时,我开始遇到重大问题。 (正如提醒我的堆栈是 privateContext -> mainContext -> privateContext Spawns)。我会使用核心数据变量的副本创建一个内存对象,然后将该变量传回,如果发生变化并且获取结果控制器在调用的地方委托,这就是我遇到主要问题的地方。
  • 已知嵌套上下文存在错误,例如不遵守fetchBatchSize 设置。您是否在直接连接到 PSC 的单一主要上下文中尝试过此操作?我认为每个上下文有可能有 1000 个对象物化,如果它们与其他物化对象有关系,它们可能不会出错。

标签: ios performance core-data nsfetchedresultscontroller nsfetchrequest


【解决方案1】:

我怀疑您没有正确使用获取的结果控制器或核心数据。我有 150.000 条记录的场景,并且更多由获取结果控制器提供支持,没有内存(或性能)问题。

一些关于没有怪癖的设置的详细信息:

  • 上下文当然是主线程上下文
  • fetchBatchSize 未设置
  • (可选)使用唯一命名的缓存(获取结果控制器初始化中的最后一个参数)
    • 您必须在重新加载此控制器时重置缓存

还要确保您没有直接在 Core Data 中存储大图像或其他BLOBs - 这肯定会降低性能并导致内存管理问题。如果您需要显示图像,请延迟加载它们。

【讨论】:

  • 不,这一切我都有充分的了解,并且如原始问题中所述,所有这些都得到了正确应用和应用。我看到的问题是内存再次被保留。
  • 不,它没有。我明确声明我设置了 fetchBatchSize 并且当它分批提取数据时,它似乎没有错误数据,它只是加载更多。
  • 说明你用过,建议不要用。
  • 对,我清楚地声明我正在使用它,并且它已按照您的说明进行设置。我明确提到我正在使用它来摆脱类似于 IT 笑话“你是否将其关闭并再次打开”的填充答案,希望对我的问题有一个有价值的答案。在企业环境中处理大量数据时,有很多关于这个确切问题的论坛和问题,所以这就是手头的问题(我已经验证过)已经不是什么秘密了。我不是在寻找生硬、重复的简单答案,而是在寻找体面的可行解决方案。
  • 问题不是“我做错了什么”。问题是,我已经正确使用了所有推荐的方法,但发现 API 存在问题,解决此问题的最佳方法是什么。
猜你喜欢
  • 1970-01-01
  • 2019-12-06
  • 1970-01-01
  • 2023-03-28
  • 2014-01-09
  • 2011-08-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多