2010-05-03 65 views
0

我使用iPhone的Objective-C的JSON Framework插件來通過HTTP捕獲一個JSON對象,該對象是一組Dictionary對象。這是我的connectionDidFinishLoading功能:iPhone JSON對象釋放自己?

- (void)connectionDidFinishLoading:(NSURLConnection *)connection { 
    [connection release]; 
NSString *responseString = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding]; 
[loadingIndicator stopAnimating]; 

NSArray *responseArray = [responseString JSONValue]; // Grab the JSON array of dictionaries 
NSLog(@"Response Array: %@", responseArray); 
if ([responseArray respondsToSelector:@selector(count)]) { 
    NSLog(@"Returned %@ items", [responseArray count]); 
} 
[responseArray release]; 
[responseString release]; 
} 

的問題是,碼在第二NSLog線扔EXC_BAD_ACCESS錯誤。我認爲EXC_BAD_ACCESS錯誤表明該變量已從內存中釋放,但第一個NSLog命令正常工作(並顯示數據全部存在);似乎只有當調用count消息導致錯誤時,但respondsToSelector調用至少認爲responseArray應該能夠響應該消息。當使用調試器運行時,它在第二行崩潰,但堆棧顯示responseArray對象仍然被定義,並且其中有12個對象(所以調試器至少能夠獲得該變量內容的準確count )。

這是JSON框架創建的那個NSArray問題,還是我的代碼有問題?

回答

2

count返回NSUInteger,而不是一個對象。每Apple Documentation你應該在這種情況下使用%lu和轉換爲unsigned long,而不是將其顯示:

NSLog(@"Returned %lu items", (unsigned long)[responseArray count]); 

隨着%@NSLog()試圖解釋值作爲一個指向對象,併發送description消息給它。
在該內存位置偶然有一個有效的對象是非常不可能的,因此代碼必然會嚴重失敗或顯示不可預知的結果。

+0

啊善良;當愚蠢的東西陷入我的時候討厭它;我通常使用'%@'作爲一個catch-all,假定甚至像NSInteger這樣的基本變量類型實際上是Objective-C中的一個對象,因此可以用該調用輸出某些東西,但顯然不是這種情況。 – MidnightLightning 2010-05-03 17:13:38

+0

@Midnight,只有Objective-C類類型的實例是對象。你必須記住,Objective-C只能擴展C. – 2010-05-04 14:03:45

+0

@gf有沒有一個列表,其中的類是「Objective-C」類型,而不是「C」類型?我曾經想過'NSUInteger'(從'NSArray''count'方法返回的東西)是一個Objective-C類型,而不是'int'類型(這是一個基本的C類型),因此應該能夠響應到「描述」消息(即使這不是處理它的最合適的方式)? – MidnightLightning 2010-05-04 14:40:46

1

簡單的錯字:第二個NSLog中的格式字符串包含%@而不是%d。

+0

'%u'實際上,'count'返回一個無符號整數。 – 2010-05-03 17:13:10

+4

@gf你說得對,我有這種不使用正確的格式說明符的懶惰習慣。但是,當我們處理它時:'count'返回一個'NSUInteger',它在iPhone OS上被typedef'ed爲'unsigned int'。在LP64(Mac OS 64位)上,它被鍵入「unsigned long」。所以我會爭論使用'%lu'作爲格式說明符。這應該適用於所有情況。 – 2010-05-04 09:47:17

+0

'%lu'是文檔推薦的,IIRC。 – Wevah 2010-05-04 11:18:08

2

除了Nikilai所說的女友,並[responseArray release];以上版本

如果那些傢伙得到了他們的方法冠名權,NSArray *responseArray = [responseString JSONValue];返回一個自動釋放的實例。

+0

而在另一個此外: 看來你不應該'釋放''連接'。你應該從不**必須考慮'釋放**你在方法中獲得的任何**變量。 – bddckr 2010-05-03 17:11:28

+0

好點;我沒有得到這麼多來觸發過度釋放錯誤! – MidnightLightning 2010-05-03 17:13:58

+0

@ChriB;我從http://www.mobileorchard.com/tutorial-json-over-http-on-the-iphone/ – MidnightLightning 2010-05-03 17:15:11