9

我有这个问题。我在 Core Data 中有一个图像数据库。我获取所有图像(大约 80MB)并放入一个 NSMutableArray。对象正确错误:

NSArray *fetchResults = [self.managedObjectContext executeFetchRequest:request error:&error];
self.cache = [NSMutableArray arrayWithArray:fetchResults];
for (ImageCache *imageObject in self.cache) {
    NSLog(@"Is fault? %i", [imageObject isFault]);
}

阅读日志,我看到对象都是正确的错误但是,使用 Instruments,我看到使用了 80MB 的内存。我认为这就是 Core Data 缓存它的结果的原因,并且应该在需要时释放内存。但是(这是我的“问题”),如果我模拟内存警告,什么都不会发生!80MB 仍然存在。

查看工具 - 分配,许多 Malloc 使用 80MB:(示例)

图表类别 Live Bytes # Living # Transitory 总体字节数 # 总体 # 分配(净/总体) 0 Malloc 176,00 KB 8,59 MB 50 57 18,39 MB 107 %0.00, %0.00 0 Malloc 200,00 KB 8,20 MB 42 460 98,05 MB 502 %0.00, %0.04 0 Malloc 168,00 KB 7,05 MB 43 19 10,17 MB 62 %0.00, %0.00

这是整个调用树图像的链接:https ://www.dropbox.com/s/du1b5a5wooif4w7/Call%20Tree.png

有任何想法吗?谢谢

4

2 回答 2

9

好的,我明白为什么会这样了。当您对实体发出获取请求时,即使启用了故障,该实体的所有数据也会加载到内存中。包括大的二进制数据。您可以使用多种方法解决此问题:

1-在您的设置上设置NSFetchRequest[request setIncludesPropertyValues:NO]; 设置否,数据不会立即加载到缓存中,而是仅在请求时加载(当您访问属性并触发故障时)但这有一个“问题”。即使您尝试再次对属性进行故障处理(因为您不需要立即使用它并且想要释放内存,使用[self.managedObjectContext refreshObject:object mergeChanges:NO];),内存也不会被释放。缓存保持活动状态,直到 managedObjectContext 被重置。

这个更好:

2-您可以将数据拆分为单独的实体。就我而言,我只有 2 个属性:一个 url 和一个图像数据。我将数据以 1:1 的关系拆分为 2 个实体:imagecache 和 imagedata。为“imagecache”实体的所有行(使用 url 属性)创建了一个 fetchRequest,并且与之前的解决方案一样,没有缓存内存。属性 imagecache.relationship.image 已正确出错。访问此属性会导致故障触发并填充缓存。但在这种情况下,[self.managedObjectContext refreshObject:object mergeChanges:NO];对“imagecache”对象(“父亲”对象)执行操作会导致立即释放缓存和内存,从而再次导致 imagecache.relationship.image 属性出错。注意:不要在“子”对象上做,如果这样做[self.managedObjectContext refreshObject:object.relationship mergeChanges:NO],由于某种原因缓存没有被释放。

3-我说这主要是一个学术问题,这个问题的真正“整天”解决方案(更好的性能和更少的头痛)是避免将大数据保存在核心数据数据库中。您可以将数据保存为文件并仅存储参考(文件路径),或者,在 iOS 5 中,您可以在核心数据模型内的任何“数据”属性上设置“使用外部存储”。这将为您完成所有工作。

于 2012-09-08T16:17:31.807 回答
0

我认为您应该将较少的对象批量加载到内存中。

coredata释放的内存发生在幕后,你不必为它编程;坏消息是它发生在幕后,因此可以“神奇地”吞噬记忆。

绕过它的方法很多;例如,使用谓词仅选择您绝对需要的行;不要进行一般调用来获取所有内容,然后一一浏览列表。当您进行一般调用并且 CoreData 尝试加载所有对象时,您很可能会崩溃。

于 2012-09-06T08:37:31.803 回答