类初始化中断应用程序
我最近为我的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]];
我在哪里这个问题呢?
我看到了一些问题。
- 你没有检查[super init]的返回值。
- 你正在存储autoreleased数组在什么大概ivars(位置和坐标)。
- 您正在传递一个单独的大小参数,该大小参数是从调用外部的rawData计算出来的,但是-initWithData:在方法内部执行完全相同的计算。 size:参数在这里看起来完全是多余的。
-
您正在完全跳过最后一个标记。你应该采取这个循环,并使条件简单
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
的电话都会崩溃。所有这4个对象都是自动释放对象,因此现在只需调用-release
就可以保证当自动释放池耗尽时应用程序会崩溃。 - 您还在
coordinates
阵列中存储coords
(例如字符串)。大概你的意思是存储coord
,虽然你需要将它包装在一个NSValue中,以便将其存储在NSArray中。
+1来获取控制台上的对象信息;我认为这对代码有很大的帮助 – 2010-10-29 14:59:41
我看到几个问题。
1)最基本的是,你发布了很多你没有分配的对象。例如:
NSString *line = [tokens objectAtIndex:i];
....
[line release];
不正确。查看Cocoa Memory Management Rules。
2)你为什么要这么做[[gpsRawData componentsSeparatedByString:@"@"] count
传递大小 您initWithData:size:
方法,当你只是将不得不重复你的方法里面-componentsSeparatedByString:
电话。传递一个单独的“大小”并不会给你带来任何好处,涉及对输入的冗余解析,并且会引发更多可能的错误(如果调用者传入的“大小”与“@”的数目不符在输入中 - 你没有处理那个错误条件)。
3)我也看到你正在给CLLocationCoordinate2D coord;
分配纬度/经度,但没有做任何事情。这是故意的吗?
控制台上是否有任何崩溃消息? – taskinoor 2010-10-29 14:48:58
没有错误检查任何参数,我会从那里开始。 – 2010-10-29 14:51:28
你在那里只有一个突破点吗?可能让你到个人的路线。您可以通过输入'po