2010-10-29 359 views
0

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

回答

6

我看到了一些問題。

  • 你沒有檢查[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

2

我看到幾個問題。

1)最基本的是,你發佈了很多你沒有分配的對象。例如:

NSString *line = [tokens objectAtIndex:i]; 
.... 
[line release]; 

不正確。查看Cocoa Memory Management Rules

2)你爲什麼要這麼做[[gpsRawData componentsSeparatedByString:@"@"] count傳遞大小 您initWithData:size:方法,當你只是將不得不重複你的方法裏面-componentsSeparatedByString:電話。傳遞一個單獨的「大小」並不會給你帶來任何好處,涉及對輸入的冗餘解析,並且會引發更多可能的錯誤(如果調用者傳入的「大小」與「@」的數目不符在輸入中 - 你沒有處理那個錯誤條件)。

3)我也看到你正在給CLLocationCoordinate2D coord;分配緯度/經度,但沒有做任何事情。這是故意的嗎?