views:

286

answers:

4
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]]];
 }
A: 

Can you use chunks bigger than 1024?

Allen
+1  A: 

You're allocating several objects for each line of the file, and they aren't getting released because they're getting added to an autorelease pool, and the autorelease pool isn't getting a chance to drain. Add an autorelease pool that drains every some number of iterations:

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];
Adam Rosenfield
Hmm, as soon as I release the pool using this code, I crash tith EXC_BAD_ACCESS
Andrew Johnson
You are not adding anything to "pool". Is that normal?
simao
If you use the autorelease pool, then it looks like gpx needs to be retained/released. Try and rewrite the loop without using any autoreleased objects.
FigBug
Can I just retain the objects I need to retain... and if so, should I retain them before each time I release the pool, or just once?
Andrew Johnson
+3  A: 

As others have pointed out, you are creating a lot of temporary objects. An awful lot. On top of that, the size of the temporary objects, at least gpx ones, is increasing with each pass of the loop. You might want to try something like:

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;

This example loads the contents of what's at gpsFilePath and splits it by new lines. Then, for each line, it splits the line on commas, and appends the results to the mutable string gpx. It wraps the processing part that creates lots of temporary objects in an autorelease pool so they get discarded as soon as possible.

At the end, the variable gpx will contain the processed results.

johne
+1  A: 

You are allocating cString without releasing or autoreleasing it. You should do a [cString release] each time when you're done with it.

Also, like the others said, you should use your own autorelease pool, and append to the existing gpx instead of creating a new string each time.

Derek Ledbetter