这个循环在iPhone上的5万行窒息......我可以改进它,所以它不是吗?

时间:2009-07-22 21:34:30

标签: iphone objective-c cocoa-touch

FILE *file = fopen([gpsFilePath UTF8String], "r");
char c[1024];

while(fgets(c, 1024, file)!=NULL)
{
    NSString *cString = [[NSString alloc] initWithCString:c
                                                 encoding:NSMacOSRomanStringEncoding];

    NSArray *split = [cString componentsSeparatedByString:@","];
    if ([split count] != 3)
    {
        continue; //this should only happen on the first line
    }

    gpx = [gpx stringByAppendingString:[NSString stringWithFormat:@"      <trkpt lat=\"%@\" lon=\"%@\"></trkpt>\n\n", [split objectAtIndex:0], [split objectAtIndex:1]]];
 }

4 个答案:

答案 0 :(得分:3)

正如其他人所指出的,你正在创造许多临时对象。太可怕了。最重要的是,临时对象的大小(至少gpx个)随着循环的每次传递而增加。你可能想尝试类似的东西:

NSMutableString *gpx = [NSMutableString string];
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
for(NSString *line in [[NSString stringWithContentsOfFile:gpsFilePath usedEncoding:NULL error:NULL] componentsSeparatedByString:@"\n"]) {
  NSArray *split = [line componentsSeparatedByString:@","];
  [gpx appendFormat:@"      <trkpt lat=\"%@\" lon=\"%@\"></trkpt>\n\n", [split objectAtIndex:0], [split objectAtIndex:1]];
}
[pool release];
pool = NULL;

此示例加载gpsFilePath处的内容并按新行分割。然后,对于每一行,它将逗号分割为行,并将结果附加到可变字符串gpx。它包装了在自动释放池中创建大量临时对象的处理部分,因此它们会被尽快丢弃。

最后,变量gpx将包含已处理的结果。

答案 1 :(得分:1)

你为文件的每一行分配了几个对象,并且它们没有被释放,因为它们被添加到自动释放池中,并且自动释放池没有机会流失。添加一个自动释放池,每个迭代次数耗尽:

NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
FILE *file = fopen([gpsFilePath UTF8String], "r");
char c[1024];
int line = 1;
while(fgets(c, 1024, file)!=NULL) {
  NSString *cString = [[NSString alloc] initWithCString:c encoding:NSMacOSRomanStringEncoding];
  NSArray *split = [cString componentsSeparatedByString:@","];
  if ([split count] != 3) { continue; }  //this should only happen on the first line
  gpx =  [gpx stringByAppendingString:[NSString stringWithFormat:@"      <trkpt lat=\"%@\" lon=\"%@\"></trkpt>\n\n",
                                      [split objectAtIndex:0],[split objectAtIndex:1]]];
  if(line % 1000 == 0)  // drain the pool every 1000 iterations
  {
    [pool release];
    pool = [[NSAutoreleasePool alloc] init];
  }
  line++;
 }
[pool release];

答案 2 :(得分:1)

您正在分配cString而不释放或自动释放它。每次完成后都应该[cString release]

此外,与其他人一样,您应该使用自己的自动释放池,并附加到现有的gpx,而不是每次都创建一个新的字符串。

答案 3 :(得分:0)

你能使用大于1024的块吗?