类初始化中断应用程序

问题描述:

我最近为我的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

控制台上是否有任何崩溃消息? – taskinoor 2010-10-29 14:48:58

+0

没有错误检查任何参数,我会从那里开始。 – 2010-10-29 14:51:28

+0

你在那里只有一个突破点吗?可能让你到个人的路线。您可以通过输入'po ' – 2010-10-29 14:59:59

我看到了一些问题。

  • 你没有检查[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中。
+0

+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;分配纬度/经度,但没有做任何事情。这是故意的吗?