gas*_*uff 5 json memory-management objective-c didreceivememorywarning ios
我正在解析一个大约53 MB的iPad上的JSON文件.解析工作正常,我正在使用Yajlparser这是一个SAX解析器,并设置如下:
NSData *data = [NSData dataWithContentsOfFile:path options:NSDataReadingMappedAlways|NSDataReadingUncached error:&parseError];
YAJLParser *parser = [[YAJLParser alloc] init];
parser.delegate = self;
[parser parse:data];
Run Code Online (Sandbox Code Playgroud)
到目前为止一切正常,但JSON文件变得更大,现在我突然在iPad 2上遇到内存警告.它收到4个内存警告,然后崩溃.在iPad 3上,它可以完美运行,没有任何内存警告.
我已经开始使用Instruments进行分析并发现了很多CFNumber分配(我已经在几分钟之后停止了仪器,我已经运行它直到崩溃并且CFNumber事件大约为60 mb或更多).

打开CFNumber详细信息后,它显示了一个巨大的分配列表.其中一个向我展示了以下内容:

还有一个在这里:

那么我做错了什么?这个数字(例如最后一张图片中的72.8%)代表什么?我正在使用ARC,所以我没有做任何发布或保留等等.
谢谢你的帮助.干杯
编辑:我已经问过如何在这里解析如此庞大的文件的问题:iPad - 解析一个非常巨大的json - 文件(介于50和100 mb之间)
所以解析本身似乎很好.
请参阅Apple有关高效导入数据的核心数据文档,尤其是"减少峰值内存占用".
您需要确保一次在内存中没有太多新实体,这包括在解析数据时定期保存和重置上下文,以及使用自动释放池.
一般的sudo代码是这样的:
while (there is new data) {
@autoreleasepool {
importAnItem();
if (we have imported more than 100 items) {
[context save:...];
[context reset];
}
}
}
Run Code Online (Sandbox Code Playgroud)
所以基本上,在主循环周围放置一个自动释放池或解析代码.计算NSManagedObject您创建的实例数,并定期保存和重置托管对象上下文以刷新这些内存.这应该可以减少你的内存占用.该数字100是任意的,您可能希望尝试不同的值.
因为您要保存每个批次的上下文,所以您可能希望导入商店的临时副本,以防出现问题并让您进行部分导入.一切都完成后,您可以覆盖原始商店.