【发布时间】:2016-07-19 12:22:29
【问题描述】:
作为允许审核员创建结果并将照片与其关联的应用程序的一部分(由于 Web 服务的限制,保存为 Base64 字符串)我必须在审核中遍历所有结果及其照片并设置它们的同步值为真。
在执行此循环时,我看到内存峰值从大约 40MB 跃升至 500MB(大约 350 张照片和 255 个结果),并且这个数字从未下降。平均而言,我们的用户在尝试使用此功能之前会创建大约 1000 个结果和 500-700 张照片。我尝试使用@autorelease 池来降低内存,但它似乎永远不会被释放。
for (Finding * __autoreleasing f in self.audit.findings){
@autoreleasepool {
[f setToSync:@YES];
NSLog(@"%@", f.idFinding);
for (FindingPhoto * __autoreleasing p in f.photos){
@autoreleasepool {
[p setToSync:@YES];
p = nil;
}
}
f = nil;
}
}
关系和保留周期如下所示
Audit 强烈引用 Finding
Finding 对 Audit 的引用很弱,对 FindingPhoto 的引用很强烈
FindingPhoto 对 Finding 的引用很弱
在能够有效地循环这些对象并设置它们的属性而不导致如此巨大的内存峰值方面,我缺少什么。我假设这与循环时将这么多 Base64 字符串加载到内存中但从未被释放有关。
【问题讨论】:
-
这些对象是如何存储和加载的?它们不会被自动释放,因为它们仍然被您正在迭代的数组保留......
-
存储在核心数据中并使用 NSFetchRequests 加载到 MutableArray 中。有没有更好的方法来加载这些,一次只加载和释放一个,因为如果太多,它会导致应用崩溃。
-
我应该提到的是,唯一执行的 FetchRequest 是 Audit 对象上的一个,其余的通过它们的关系访问,而不是显式加载。
-
如何将照片存储为外部文件并让核心数据实体提供对这些文件之一的引用(路径、URL...)?这样一来,加载核心数据关系的占用空间就会很小,而且您可以明确控制内存中的照片数量。
-
@PhillipMills 就像将核心数据中的 Base64 属性标记为“存储在外部记录文件中”一样简单,还是我必须全力以赴并实际写入文件存储或生成路径读回图像时到文件?
标签: core-data automatic-ref-counting autorelease