Lom*_*baX 9 xcode memory-management core-data objective-c ios
我有这个问题.我在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]);
}
Run Code Online (Sandbox Code Playgroud)
阅读日志,我看到对象都是正确的故障然而,使用Instruments,我看到使用了80MB的内存.我认为这就是为什么Core Data会缓存它的结果,并且应该在需要时释放内存.但是(这是我的"问题"),如果我模拟一个内存警告,没有任何反应!80MB仍在那里.
看看仪器 - 分配,许多Malloc使用80MB :(示例)
图表类别实时字节#Living#Transitory Total Bytes#Overall#Allocations(Net/Overall)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
有任何想法吗?谢谢
好的,我已经明白为什么会这样.当您对实体进行获取请求时,即使启用了错误操作,该实体的所有数据也会加载到内存中.包括大二进制数据.您可以使用许多方法解决此问题:
1-设置为NSFetchRequest
:[request setIncludesPropertyValues:NO];
设置NO,数据不会立即加载到缓存中,而是仅在请求时(当您访问属性并且故障被触发时)但这有"问题".即使你试图再次故障(因为你不需要它立即想要释放内存,使用[self.managedObjectContext refreshObject:object mergeChanges:NO];
),内存也不会被释放.缓存保持活动状态,直到重置managedObjectContext.
这个更好:
2-您可以将数据拆分为单独的实体.在我的情况下,我只有2个属性:网址和图像数据.我将数据拆分为2个实体,关系为1:1: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,您可以在核心数据模型中的任何"数据"属性上设置"使用外部存储".这将为您完成所有工作.
归档时间: |
|
查看次数: |
5468 次 |
最近记录: |