【问题标题】:iOS NSMutableArray to NSString and then save to device >>> out of memoryiOS NSMutableArray 到 NSString 然后保存到设备 >>> 内存不足
【发布时间】:2014-07-13 04:44:42
【问题描述】:

我有一个 NSMutableArray,里面有很多这样的行(GPS 数据,一小时 3600 行)

51.040987|12.379154|183|599|0.0|0.0|2014-05-23T17:48:02Z|321.4

在一个循环中,我将这些值组合成一个 xml 字符串。

像这样

xmlExport = [NSString stringWithFormat:@"%@\t\t<trackpoint>\n\t\t\t<latitude>%@</latitude>\n\t\t\t<longitude>%@</longitude>\n\t\t\t<altitudemeter>%@</altitudemeter>\n\t\t\t<altitudefeet>%@</altitudefeet>\n\t\t\t<speedkmh>%@</speedkmh>\n\t\t\t<speedmph>%@</speedmph>\n\t\t\t<datetime>%@</datetime>\n\t\t\t<degree>%@</degree>\n\t\t</trackpoint>\n", xmlExport,[CoordsArray objectAtIndex: 0], [CoordsArray objectAtIndex: 1], [CoordsArray objectAtIndex: 2], [CoordsArray objectAtIndex: 3], [CoordsArray objectAtIndex: 4], [CoordsArray objectAtIndex: 5], [CoordsArray objectAtIndex: 6], [CoordsArray objectAtIndex: 7]];

而且我想将这些数据作为 xml 文件保存在设备上,就像这样

NSString *fileNameCSV = [NSString stringWithFormat:@"%@/export_%@.csv", documentsDirectory, date2];
success = [csvExport writeToFile:fileNameCSV atomically:YES encoding:NSUTF8StringEncoding error:&error];

使用较少的数据一切正常,但是当我有大约/超过 1500 行时,我遇到内存问题并且应用程序崩溃,在模拟器中一切正常。

问题不是保存文件,我认为更多是在组合xml字符串时的for循环。

还有其他方法可以将数据保存到设备吗?

这是我的自动释放池代码

    for (NSString *line in coords) {

    @autoreleasepool {

        NSArray* CoordsArray = [line componentsSeparatedByString:@"|"];

        if(ExportType2==2){
            xmlExport = [NSString stringWithFormat:@"%@\t\t<trackpoint>\n\t\t\t<latitude>%@</latitude>\n\t\t\t<longitude>%@</longitude>\n\t\t\t<altitudemeter>%@</altitudemeter>\n\t\t\t<altitudefeet>%@</altitudefeet>\n\t\t\t<speedkmh>%@</speedkmh>\n\t\t\t<speedmph>%@</speedmph>\n\t\t\t<datetime>%@</datetime>\n\t\t\t<degree>%@</degree>\n\t\t</trackpoint>\n", xmlExport,[CoordsArray objectAtIndex: 0], [CoordsArray objectAtIndex: 1], [CoordsArray objectAtIndex: 2], [CoordsArray objectAtIndex: 3], [CoordsArray objectAtIndex: 4], [CoordsArray objectAtIndex: 5], [CoordsArray objectAtIndex: 6], [CoordsArray objectAtIndex: 7]];
        }

        if(ExportType2==3){
            kmlExport = [NSString stringWithFormat:@"%@,%@,%@,%@", kmlExport,[CoordsArray objectAtIndex: 1], [CoordsArray objectAtIndex: 0], [CoordsArray objectAtIndex: 2]];
        }

        if(ExportType2==4){
            gpxExport = [NSString stringWithFormat:@"%@\t\t<trkpt lat=\"%@\" lon=\"%@\">\n\t\t\t<ele>%@</ele>\n\t\t\t<time>%@</time>\n\t\t\t<magvar>%@</magvar>\n\t\t</trkpt>\n", gpxExport,[CoordsArray objectAtIndex: 0], [CoordsArray objectAtIndex: 1], [CoordsArray objectAtIndex: 2], [CoordsArray objectAtIndex: 6], [CoordsArray objectAtIndex: 7]];
        }

        //NSLog([NSString stringWithFormat:@"line: %@", line]);
        //NSLog([NSString stringWithFormat:@"gpxExport: %@", gpxExport]);

    }
}

现在应用程序在数据很少的情况下也崩溃了

self    Class   MailBuilder 0x00115f58
coords  __NSArrayM *    @"29 objects"   0x15e5e960
line    __NSCFString *  @"51.041037|12.379055|0|0|0.0|0.0|2014-05-23T18:29:17Z|297.6"   0x15e497f0
CoordsArray __NSArrayM *    @"8 objects"    0x17dde2a0
xmlExport   NSString *  0x17d39a00  0x17d39a00

【问题讨论】:

  • 您也可以使用-[NSMutableString appendFormat:...],这将在保持基本格式的同时大有帮助。更好的办法是逐行将数据写入文件,这样可以将内存使用量减少到几乎为零。
  • 显示您的代码! @autoreleasepool{} 可能就是您所需要的。
  • 我已经编辑了我的帖子并插入了我使用的代码
  • 当您在 Instruments 中对此进行分析时,您看到了什么?您确实对此进行了分析,对吗?
  • 我应该从仪器中粘贴什么

标签: ios iphone memory nsstring nsmutablearray


【解决方案1】:

将循环的inside包裹在autoreleasepool中,像这样:

for (...) { // or however you are looping
    @autoreleasepool {
        // .... everything else
    }
}

这将导致 1 个循环和 1500 个循环使用相同数量的内存。

【讨论】:

  • 它仍然会使用至少两倍的内存,因为他的基本格式是string = [NSString stringWithFormat:@"%@, ...", string] 所以至少他有旧字符串和新字符串。它会有所帮助,但不一定在所有情况下都足够。实际上,最好的方法是逐行写出来。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-06-09
  • 2018-07-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多