【发布时间】:2013-08-30 06:31:02
【问题描述】:
我正在解析一个大小约为 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];
到目前为止一切正常,但 JSON 文件变大了,现在我突然在 iPad 2 上遇到内存警告。它收到 4 个内存警告,然后就崩溃了。在 iPad 3 上,它可以完美运行,没有任何内存警告。
我已经开始使用 Instruments 对其进行分析,并发现了很多 CFNumber 分配(几分钟后我停止了 Instruments,我之前运行它直到崩溃并且 CFNumber 的东西大约是 60 mb 或更多)。
打开 CFNumber 详细信息后,它显示了一个巨大的分配列表。其中一个向我展示了以下内容:
这里还有一个:
那我做错了什么?这个数字(例如最后一张图片中的 72.8%)代表什么?我正在使用 ARC,所以我没有做任何 Release 或 Retain 或其他任何事情。
感谢您的帮助。 干杯
编辑:我已经在这里问过如何解析如此大的文件的问题:iPad - Parsing an extremely huge json - File (between 50 and 100 mb)
所以解析本身似乎没问题。
【问题讨论】:
-
这个数字意味着这部分代码导致您面临的主要问题的可能性为 72.8%。 (除了少数之外,它大部分时间都指向正确的方向)。仅仅因为您使用 ARC 并不意味着 100% 无错误/无泄漏代码。例如,循环引用仍然会导致代码泄漏。尝试运行内存分析器,看看您的“虚拟内存”是否变得太大。请发布您的反馈
-
据我了解,CoreFoundation 确实会尽量减少对象实例的数量,例如数字和字符串。属性“kundennr”是否被定义为“副本”?看起来您可能会在每次分配该属性和“currentWarengruppeVK”时进行复制。这将抵消 CoreFoundation 提供的内置效率。
-
YAJL 解析器的一个潜在问题是它为原始 JSON 值(String、True、False、Number、Null)传递 NSObject。也就是说,它必须在内部为此分配 NSObjects。很可能,这些对象也将被放入自动释放池中。更好的方法不会分配任何东西来将 JSON 原始值传递给解析器的委托。通常(例如创建 CD 托管对象),这也是不必要的。无论如何,CD 托管对象都会为其属性创建副本。简而言之:IMO,YAJL 似乎不适合您的问题。
-
一个具有潜在巨大治疗效果的小提示:不要将 NSNumber 用于“Kundennummer”。如果您的 Kundennummer" 不适合整数或包含非数字字符,您将遇到严重的麻烦。NSNumber 不会警告您!最好使用字符串。
-
@Dan_Gabicoware,不,kundennr 是这样定义的
@property (nonatomic, retain) NSNumber * kundennr;,它是一个由 Xcode(NSManagedObject 子类)创建的实体。
标签: ios objective-c json memory-management didreceivememorywarning