Iphone 类初始化中断应用程序

Iphone 类初始化中断应用程序,iphone,objective-c,cocoa-touch,xcode,Iphone,Objective C,Cocoa Touch,Xcode,我最近为我的iPhone应用程序创建了一个新类,它将保存从包含街道地址和感兴趣的GPS点的文本文件中读取的信息 但问题是,每当我添加代码初始化类时,我的应用程序就会加载,并且控制台中不会出现错误,立即退出。当我移除它时,一切都很好。我根本看不出代码有什么问题 以下是构造函数: #import "GPSCoordinate.h" @implementation GPSCoordinate -(GPSCoordinate*) initWithData:(NSString *)rawData si

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

我在这方面哪里出了问题?

我看到了一些问题

  • 您没有检查[super init]的返回值
  • 您将自动释放的数组存储在可能的IVAR(位置和坐标)中
  • 您正在传递一个单独的size参数,该参数是从调用外部的rawData计算出来的,但是-initWithData:在方法内部进行完全相同的计算。size:参数在这里似乎完全多余
  • 您完全跳过了最后一个标记。您应该将其作为循环,并将条件简化为
    i
    。或者,如果您的目标是iOS 4.0或更高版本,您可以将整个循环转换为

    [tokens enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop){
        NSString *line = obj;
        // rest of loop body
    }];
    
    由于您似乎不需要循环内的索引,因此也可以使用for-in循环(这将适用于4.0 iOS之前的设备):

  • 您没有检查您的数据是否有效。如果一行包含“foo”,当您的程序试图访问
    [lineTokens objectAtIndex:1]
    时,它将崩溃。类似地,当字符串“foo:”试图删除
    坐标
    变量的第一个字符时,它也会崩溃。事实上,冒号后少于2个字符的任何内容都会崩溃。如果冒号后面没有空格,它也会崩溃

  • 最后,最后所有对
    -release
    的调用都将崩溃。所有这4个对象都是自动释放对象,因此现在通过对它们调用
    -release
    ,您可以简单地保证当自动释放池耗尽时应用程序将崩溃
  • 您还在
    坐标
    数组中存储
    坐标
    (例如字符串)。您可能打算存储
    coord
    ,但需要将其包装在NSValue中,以便将其存储在NSArray中
    • 我看到了几个问题

      1) 最基本的是,您正在释放许多未分配的对象。例如:

      NSString *line = [tokens objectAtIndex:i];
      ....
      [line release];
      
      这是不正确的。回顾历史

      2) 为什么要执行
      [[gpsRawData componentsSeparatedByString:@“@”]count
      将大小传递给 您的
      initWithData:size:
      方法,当您只需要在方法内部重复
      -componentsSeparatedByString:
      调用时。传递单独的“size”不会给您带来任何好处,涉及对输入的冗余解析,并打开更多可能的bug(如果调用方传入“size”怎么办这与输入中“@”的数目不匹配-您没有处理该错误条件)


      3) 我还看到您正在将纬度/经度分配给
      cllocationcoordinae2d coord;
      ,但没有对其进行任何操作。这是故意的吗?

      控制台上是否有任何崩溃消息?在任何参数上都没有错误检查,我将从那里开始。您在其中只有一个断点吗?可能会让您转到单独的行。Y您可以在控制台上通过键入for in建议的
      po
      +1来获取有关对象的信息;我认为这对编写此代码会有很大帮助
      for (NSString *line in tokens) {
          // body of loop
      }
      
      NSString *line = [tokens objectAtIndex:i];
      ....
      [line release];