I’ve recently created a new class for my iPhone application which will hold information read from a text file containing the street address and GPS points of points of interest.
The issue though is that whenever I add code to initialize the class my application loads up and the instantly quits with no errors in the console. When I remove it, everything is fine. I simply cannot see anything wrong with the code.
Here is the constructor:
#import "GPSCoordinate.h"
@implementation GPSCoordinate
-(GPSCoordinate*) initWithData:(NSString *)rawData size:(int)size
{
self = [super init];
location = [NSMutableArray arrayWithCapacity:size];
coordinates = [NSMutableArray arrayWithCapacity:(int)size];
NSArray *tokens = [rawData componentsSeparatedByString:@"@"];
for (int i = 0; i < size - 1; i++) {
//Sub tokens
NSString *line = [tokens objectAtIndex:i];
NSArray *lineTokens = [line componentsSeparatedByString:@":"];
//Store address
[location addObject:[lineTokens objectAtIndex:0]];
//Store GPS coords
NSString *coords = [lineTokens objectAtIndex:1];
coords = [[coords stringByReplacingCharactersInRange:NSMakeRange(0, 1) withString:@""]
stringByReplacingCharactersInRange:NSMakeRange([coords length]-2, 1) withString:@""];
NSArray *coordsTokens = [coords componentsSeparatedByString:@" "];
CLLocationCoordinate2D coord;
coord.latitude = [[coordsTokens objectAtIndex:0] doubleValue];
coord.longitude =[[coordsTokens objectAtIndex:1] doubleValue];
[coordinates addObject:coords];
[line release];
[lineTokens release];
[coords release];
[coordsTokens release];
}
return self;
}
@end
Here is the call I make to it in another class:
self.gps = [[GPSCoordinate alloc] initWithData:gpsRawData size:[[gpsRawData componentsSeparatedByString:@"@"] count]];
Where am I going wrong with this?
I see a number of problems.
You’re skipping the last token entirely. You should take that for loop and make the condition simply
i < size. Alternately if you’re targetting iOS 4.0 or above you can turn the entire loop intoSince you don’t seem to need the index inside the loop, you could also just use a for-in loop (this will work on pre-4.0 iOS devices):
You’re not checking that your data is valid. If a line contains “foo”, your program will crash when it tries to access
[lineTokens objectAtIndex:1]. Similarly it’ll crash if you have the string “foo:” as it tries to remove the first character of thecoordinatesvariable. In fact anything less than 2 characters after the colon will crash. It’ll also crash if there’s no spaces after the colon.-releaseat the end will crash. All 4 of those objects are autoreleased objects, so by calling-releaseon them now you’re simply guaranteeing that the app will crash when the autorelease pool is drained.coords(e.g. the string) in yourcoordinatesarray. Presumably you meant to storecoord, though you’ll need to wrap it in an NSValue in order to store it in an NSArray.