我最近为我的iPhone应用程序创建了一个新类,它将保存从包含街道地址和感兴趣点的GPS点的文本文件中读取的信息。
问题是,无论何时我添加代码来初始化类,我的应用程序都会加载并立即退出,控制台中没有错误。当我删除它,一切都很好。我根本看不出代码有什么问题。
这是构造函数:
#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
以下是我在另一个课程中对其进行的调用:
self.gps = [[GPSCoordinate alloc] initWithData:gpsRawData size:[[gpsRawData componentsSeparatedByString:@"@"] count]];
我在哪里错了?
答案 0 :(得分:6)
我看到了很多问题。
您正在完全跳过最后一个令牌。你应该把它换成循环并简单地使条件i < size
。或者,如果您的目标是iOS 4.0或更高版本,则可以将整个循环转换为
[tokens enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop){
NSString *line = obj;
// rest of loop body
}];
由于您似乎不需要循环内的索引,您也可以只使用for-in循环(这适用于4.0之前的iOS设备):
for (NSString *line in tokens) {
// body of loop
}
您没有检查您的数据是否有效。如果某行包含“foo”,则程序在尝试访问[lineTokens objectAtIndex:1]
时会崩溃。类似地,如果你有字符串“foo:”,它会崩溃,因为它试图删除coordinates
变量的第一个字符。实际上,冒号后的任何小于2个字符都会崩溃。如果冒号后面没有空格,它也会崩溃。
-release
的所有调用都会崩溃。所有这四个对象都是自动释放的对象,因此现在通过调用-release
来确保应用程序在自动释放池耗尽时崩溃。coords
数组中存储coordinates
(例如字符串)。大概你打算存储coord
,虽然你需要将它包装在NSValue中以便将它存储在NSArray中。答案 1 :(得分:2)
我看到了几个问题。
1)最根本的是,你发布了许多你没有分配的对象。例如:
NSString *line = [tokens objectAtIndex:i];
....
[line release];
不正确。查看Cocoa Memory Management Rules。
2)你为什么要[[gpsRawData componentsSeparatedByString:@"@"] count
传递大小
当您需要在方法中重复initWithData:size:
调用时,您的-componentsSeparatedByString:
方法。传递一个单独的“大小”并没有获得任何东西,涉及输入的冗余解析,并打开更多可能的错误(如果调用者传入的“大小”与“@”的数量不匹配,该怎么办?在输入中 - 您没有处理该错误条件。)
3)我也看到你正在为CLLocationCoordinate2D coord;
分配纬度/经度,但没有对它做任何事情。这是故意的吗?