从for循环生成字符串会导致iOS上的内存过载

时间:2014-07-29 18:01:18

标签: ios for-loop memory-management nsstring out-of-memory

所以我在这里遇到了记忆问题。 我试图从一组位置对象生成一个GPX字符串。

我有这个函数来解析我在数组中的每个对象,并将信息添加到GPX字符串。我的数组可以包含1000多个对象,因此for循环可以运行很长时间并生成很多字符串。

- (NSString *) createGPXFromPositions:(NSArray*)pPositions andHikeName:(NSString*)pHikeName{

@autoreleasepool {

    NSDateFormatter *formatter;
    NSString        *dateString;

    formatter = [[NSDateFormatter alloc] init];
    //[formatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];

    formatter.dateFormat = @"yyyy'-'MM'-'dd'T'HH':'mm':'ss'Z'";

    dateString = [formatter stringFromDate:[NSDate date]];

    NSString *lText = @"<gpx xmlns=\"http://www.topografix.com/GPX/1/1\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" version=\"1.1\" xsi:schemaLocation=\"http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd\" creator=\"MyApp\">\n\r";
    lText = [NSString stringWithFormat:@"%@<trk>\n\r", lText];
    lText = [NSString stringWithFormat:@"%@<name>%@</name>\n\r", lText, pHikeName];
    lText = [NSString stringWithFormat:@"%@<desc>%@</desc>\n\r", lText, dateString];
    lText = [NSString stringWithFormat:@"%@<trkseg>\n\r", lText];

    for (int i=0; i<pPositions.count; i++) {

        EMTrackPoint *lLocation = [pPositions objectAtIndex:i];

        @autoreleasepool {
            lText = [NSString stringWithFormat:@"%@<trkpt lat=\"%f\" lon=\"%f\">\n\r", lText, lLocation.coordinate.latitude, lLocation.coordinate.longitude];
            lText = [NSString stringWithFormat:@"%@<ele>%f</ele>\n\r", lText, lLocation.altitude];
            lText = [NSString stringWithFormat:@"%@<time>%@</time>\n\r", lText, [formatter stringFromDate:lLocation.timestamp]];
            lText = [NSString stringWithFormat:@"%@<extensions speed=\"%f\"/>\n\r", lText, lLocation.mSpeed];
            lText = [NSString stringWithFormat:@"%@</trkpt>\n\r", lText];
        }

    }

    lText = [NSString stringWithFormat:@"%@</trkseg>\n\r", lText];
    lText = [NSString stringWithFormat:@"%@</trk>\n\r", lText];
    lText = [NSString stringWithFormat:@"%@</gpx>\n\r", lText];

    return lText;
}

}

根据这个帖子的建议,我添加了autoreleasepool声明,但这没有任何帮助: running out of memory from for loop

我从dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0),^ {})中调用createGPXFromPositions;拨打:

UIApplication * application = [UIApplication sharedApplication];
__block UIBackgroundTaskIdentifier background_task;
background_task = [application beginBackgroundTaskWithExpirationHandler:^ {

    //Clean up code. Tell the system that we are done.
    [application endBackgroundTask: background_task];
    background_task = UIBackgroundTaskInvalid;
}];

//To make the code block asynchronous
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

    NSString *lGPX = [mTraceRecorder createGPXFromPositions:mTraceRecorder.mUserTrace andHikeName:mHikeInfo.mName];

    //Clean up code. Tell the system that we are done.
    [application endBackgroundTask: background_task];
    background_task = UIBackgroundTaskInvalid;
});

然而,在一些循环之后,我遇到了内存压力问题,我遇到了didReceiveMemoryWarning,然后我的应用程序崩溃了。

我认为调用stringWithFormat会分配内存,但是当我使用ARC时,我的字符串应该在不再需要时释放,对吧? 这可能是一个noob问题,但如果有人能帮助我理解我做错了什么以及我应该在这里应用的最佳实践,我会非常感激!

1 个答案:

答案 0 :(得分:0)

我没有关注问题的原因,而是专注于其后果。 由于NSString有一个stringByAppendingString方法,我没有考虑使用NSMutableStrings。基本的初级开发人员错误,感谢帮助我解决Hot Licks,duci9y和Bruno Werminghoff!