2010-09-26 55 views
1

我收到了蘋果的崩潰報告,我試圖確定發生了什麼事。我無法按照他們的步驟重新創建崩潰,並且在我的任何測試中我都沒有看到類似的崩潰。這裏是崩潰報告的重要部分:這個對象是如何過早釋放的?

9 libobjc.A.dylib     0x00004838 objc_exception_throw + 64 
10 CoreFoundation     0x000a167c -[NSObject(NSObject) doesNotRecognizeSelector:] + 96 
11 CoreFoundation     0x000491d2 ___forwarding___ + 502 
12 CoreFoundation     0x00048f88 _CF_forwarding_prep_0 + 40 
13 TheApp       0x0001cd28 -[Tumblelog initWithDictionary:] (Tumblelog.m:40) 
14 TheApp       0x0001ef8c -[TumblrEngine userFromRequest:] (TumblrEngine.m:589) 

這看起來像我像我的字典過早發佈。此代碼路徑在應用程序的大多數運行過程中被多次調用,並且它尚未爲我崩潰,所以我相信我不會意外地將錯誤的對象發送到initWithDictionary

這裏是代碼TumblrEngineTumblelog

// TumblrEngine.m 
- (TumblrUser *)userFromRequest:(ASIHTTPRequest *)request{ 
    NSData *data = [request responseData]; 
    NSError *parseError = nil; 
    NSXMLDocument *doc = [[[NSXMLDocument alloc] initWithData:data options:NSXMLDocumentTidyXML error:&parseError] autorelease]; 
    NSDictionary *dictionary = [doc toDictionary]; 
    NSDictionary *userDict = [dictionary valueForKeyPath:kParseKeyPathUserInfo]; 
    TumblrUser *user = [[TumblrUser alloc] initWithDictionary:userDict]; 
    NSArray *tumblelogs = [dictionary valueForKeyPath:kParseKeyPathTumblelogsInfo]; 
    NSMutableArray *userTumblelogs = [NSMutableArray array]; 
    for(NSDictionary *tumblelogDictionary in tumblelogs){ 
     Tumblelog *tumblelog = [[Tumblelog alloc] initWithDictionary:tumblelogDictionary]; //line 589 
     [userTumblelogs addObject:tumblelog]; 
     [tumblelog release]; 
    } 
    [user setTumblelogs:userTumblelogs]; 
    return [user autorelease]; 

} 

// Tumblelog.m 
- (id)initWithDictionary:(NSDictionary *)aDictionary{ 
    if((self = [super init])){ 
     [self setAvatarURL:[aDictionary restURLForKey:kParseKeyTumblelogAvatarURL]]; //line 40 
     // this was the line that started the crash 
    } 
    return self; 
} 

我的主要問題是:你看到它是如何成爲可能的aDictionary在創建時將在之間的任何點釋放,當我試圖在Tumblelog.m使用它?

否則,我正在探索加載NSDictionary類別時是否有問題。當我直接將應用程序加載到我的三個測試手機(iPhone 4/iOS 4.1,iPhone 3GS/iOS 4.0.1,iPhone 3G/3.1.3)上時,它工作正常。該應用程序崩潰的手機是iPhone 4/iOS 4.1,與我的主測試手機完全相同。

我能想到的唯一的其他事情可能是我發送蘋果的二進制文件被損壞了。我懷疑這是答案,因爲這些二進制文件是可以檢查的,但是我在這裏沒有想法。如果測試儀的手機再次崩潰,我不想重新提交。

+2

這太糟糕了,你不能重新創建崩潰。它從堆棧跟蹤中看到我更有可能無論你傳入什麼 - [Tumblelog initWithDictionary:]實際上不是一個NSDictionary。然後該方法在其上調用NSDictionary方法,導致「無法識別選擇器」異常。你確定tumblelogs數組中的每個對象總是一個NSDictionary(這是在doc的toDictionary中鍵kParseKeyPathTumblelogsInfo的值總是NSDictionaries的數組)? – 2010-09-26 02:35:39

+0

我不熟悉NSXMLDocument toDictionary(並且找不到文檔?)知道這個,但是它保證'[字典valueForKeyPath:kParseKeyPathTumblelogsInfo]'將返回一個NSArray的NSDictionary實例嗎?傳入的數據符合您期望的XML,您根本不會進行任何錯誤檢測。 – imaginaryboy 2010-09-26 03:59:18

+0

非常好的點數。接收格式與我預期不同的響應數據肯定會成爲問題。我正計劃添加像@imaginaryboy建議的錯誤檢查。在正常情況下,錯誤的XML響應不會使它深入到代碼中,它們早已被捕獲。我擔心的是,這不是問題,我只是重新提交將被拒絕的應用程序。 – kubi 2010-09-26 12:23:00

回答

1

它可能是一個線程問題(其中的對象正在另一個線程上釋放),但這似乎不太可能與上面的代碼。

這很可能(正如@imaginaryboy所說)你沒有真正的字典。

更安全的循環看起來像這樣。

for(id tumblelogDictionary in tumblelogs){ 
    if ([tumblelogDictionary isKindOfClass:[NSDictionary class]]) { 
     Tumblelog *tumblelog = [[Tumblelog alloc] initWithDictionary:tumblelogDictionary]; //line 589 
     [userTumblelogs addObject:tumblelog]; 
     [tumblelog release]; 
    } else { 
     // Appropriate error handling and/or logging. 
    } 
} 

注意:我沒有真正嘗試過編譯它。它可能有一個錯字或語法錯誤或兩個。

+0

謝謝。在這種情況下,只要檢查數組中是否有字典就可以接受。除非任何人有想法,否則我無法接收字典陣列的唯一方法就是如果我從服務器獲取了錯誤的HTML。如果是這樣的話,把'tumblelog'留空將是一個可以接受的結果。 – kubi 2010-09-26 21:28:37