内存增加每次核心数据迭代
Posted
技术标签:
【中文标题】内存增加每次核心数据迭代【英文标题】:Memory increasing every core data iteration 【发布时间】:2013-05-14 00:11:57 【问题描述】:在遍历我的核心数据对象时出现内存问题。当它循环通过 CFData(存储)时,它会不断增加,直到应用程序崩溃。每次循环结束后核心数据不应该释放内存吗?
for (Patient *patient in self.fetchedResultsController.fetchedObjects)
for (Exam *examForPatient in patient.exams)
//do stuff with examForPatient
编辑 - 尝试了以下操作,但行为仍然相同:
for (Patient *patient in self.fetchedResultsController.fetchedObjects)
for (Exam *examForPatient in patient.exams)
NSLog(@"%@", [examForPatient.examDate description]);
[self.fetchedResultsController.managedObjectContext refreshObject:examForPatient mergeChanges:NO];
[self.fetchedResultsController.managedObjectContext refreshObject:patient mergeChanges:NO];
【问题讨论】:
@ikinciviking 即使是examForPatient 中字符串的NSLog 也会导致它 不,每次访问对象时,它都会通过将其加载到内存中来解决故障,并且它会一直保留在内存中,直到您告诉核心数据释放它们为止。 您的所有Patient
和相关Exam
实体都存在错误,它们将在主运行循环完成其循环之前不会被释放。尝试在内部循环周围使用@autoreleasepool
,或刷新不再需要的对象。
@DanShelly:这些技术都不会释放托管对象的内存。
@lnafziger 刷新并且对象不会释放内存?并且@autoreleasepool
用于 Apple 的许多示例中
【参考方案1】:
当您不再需要某个项目驻留在内存中时,您可以刷新它。 来自文档:“如果您迭代大量对象,您可能需要使用本地自动释放池块来确保尽快释放临时对象”
编辑:见@lnafziger回答
注意:如果您正在更新患者对象或检查对象,则无法刷新它,因为您将丢失对它的所有更改(如果您使用mergeChanges:YES
,您将不会释放它的内存)。然后,您需要定期保存并刷新不再需要的对象。
See here 了解更多信息。
【讨论】:
如果您不再引用这些对象,那么顶部关于使用 autoreleasepool 的引用是绝对正确的。然而,自动释放池在这里不起作用,因为我们仍然有有效的引用,而且它们不是你引用的“临时对象”。 但是,您从我的回答中逐信复制的代码可以正常工作。 :-)【参考方案2】:每当您访问托管对象时,它都会触发错误并从存储中加载完整的对象。除非您明确告知它,否则它不会释放内存。将您的代码更改为:
for (Patient *patient in self.fetchedResultsController.fetchedObjects)
for (Exam *examForPatient in patient.exams)
//do stuff with examForPatient
// Then release the memory. As below, save first if needed.
[yourManagedObjectContext refreshObject:examForPatient mergeChanges:NO];
// Then release the memory - save patient first if you have made changes to it.
[yourManagedObjectContext refreshObject:patient mergeChanges:NO];
【讨论】:
嗯...添加到 [patient.managedObjectContext refreshObject:patient mergeChanges:NO];它仍然表现相同。错误的 MOC? 如果一位患者的检查次数过多,您可能需要对检查执行相同的操作。我将更新我的示例。以上是关于内存增加每次核心数据迭代的主要内容,如果未能解决你的问题,请参考以下文章