iOS 高效地从 Documents Dir 中解析大型 JSON
Posted
技术标签:
【中文标题】iOS 高效地从 Documents Dir 中解析大型 JSON【英文标题】:iOS Efficiently Parse Large JSONs from Documents Dir 【发布时间】:2013-02-01 21:59:03 【问题描述】:当我加载我的应用程序时,我会下载大约 10-15 个 JSON 文件并将它们存储到我的应用程序文档目录中——其中一些文件的大小从几 KB 到 30MB 不等。
完成后,我需要从文档目录中获取它们中的每一个,转换为 NSDictionary,然后解析为 NSManagedObjects。
但是,当我使用下面的代码执行此操作时,当它通过每个 JSON 时,它似乎将它们保留在内存中,直到应用程序最终崩溃。 Instruments 在“泄漏”工具中没有显示任何内容,但我的应用程序在内存中保留了大量内容。
以下是获取 JSON 文件的代码:
更新
- (void)parseDownloadedFiles
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *docDir = [paths objectAtIndex:0];
docDir = [docDir stringByAppendingString:@"/jsons"];
NSFileManager *fileManager = [NSFileManager defaultManager];
NSError *error;
NSArray *files = [fileManager contentsOfDirectoryAtPath:docDir error:&error];
if (files == nil)
// error...
for (NSString *file in files)
NSString *fileName = [NSString stringWithFormat:@"%@/jsons/%@",
docDir, file];
NSString *content = [[NSString alloc] initWithContentsOfFile:fileName
usedEncoding:nil
error:nil];
NSDictionary *JSON =
[NSJSONSerialization JSONObjectWithData: [content dataUsingEncoding:NSUTF8StringEncoding]
options: NSJSONReadingMutableContainers
error: &error];
...create my NSManagedObjects & store
JSON = nil;
--
以下是我的分配:
--
深入了解第一个 Malloc 44.79 带来了以下问题:
-- 这是在上面代码的for循环中
NSLog 真的会导致这样的问题吗?
【问题讨论】:
【参考方案1】:您应该将 @autoreleasepool 放在读取文件的那个循环中。对象在方法返回之前不会被释放,因此内存会在循环内堆积。
ARC 将通过自动释放对象来帮助您,但您需要它们更快地释放。
https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/MemoryMgmt/Articles/mmAutoreleasePools.html
【讨论】:
我确实有一个封闭外循环的自动释放池——但是一旦我向内循环添加了一个,它的性能就会好得多。我仍然看到一些大约 50mb 的峰值,但在该文件完成处理后它会下降。我将在我的 JSON 上实现分页以减小它们的大小。谢谢【参考方案2】:是的,您的 getContentFromFile... 方法正在返回一个保留的字符串。而且你永远不会在接收端释放它。
您需要在返回时自动释放字符串,或者在将其解析为 JSON 后显式释放。
(我认为 Analyzer 会发现这个。)
【讨论】:
这不是用 ARC 处理的吗? 我最终将该函数合并到第一个函数中,但我仍然看到相同的内存积累结果。我更新了上面的截图。谢谢! @RyanG - 这就像你没有启用 ARC。或者,也许正如 jsd 所暗示的那样,您没有返回空闲循环,您需要一个自动释放池。以上是关于iOS 高效地从 Documents Dir 中解析大型 JSON的主要内容,如果未能解决你的问题,请参考以下文章
使用 System.IO.Packaging 在 c# 中解压缩 zip 文件