2010-05-10 80 views
6

我真的不知道爲什麼我的代碼拋出一個EXC_BAD_ACCESS,我按照蘋果的文檔中的準則:異步NSURLConnection的拋出EXC_BAD_ACCESS

-(void)getMessages:(NSString*)stream{ 

    NSString* myURL = [NSString stringWithFormat:@"http://www.someurl.com"]; 

    NSURLRequest *theRequest = [NSURLRequest requestWithURL:[NSURL URLWithString:myURL]]; 

    NSURLConnection *theConnection=[[NSURLConnection alloc] initWithRequest:theRequest delegate:self]; 
    if (theConnection) { 
     receivedData = [[NSMutableData data] retain]; 
    } else { 
     NSLog(@"Connection Failed!"); 
    } 

} 

我的委託方法

#pragma mark NSURLConnection Delegate Methods 
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response 
{ 
    // This method is called when the server has determined that it 
    // has enough information to create the NSURLResponse. 

    // It can be called multiple times, for example in the case of a 
    // redirect, so each time we reset the data. 

    // receivedData is an instance variable declared elsewhere. 
    [receivedData setLength:0]; 
} 

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data 
{ 
    // Append the new data to receivedData. 
    // receivedData is an instance variable declared elsewhere. 
    [receivedData appendData:data]; 
} 

- (void)connection:(NSURLConnection *)connection 
    didFailWithError:(NSError *)error 
{ 
    // release the connection, and the data object 
    [connection release]; 
    // receivedData is declared as a method instance elsewhere 
    [receivedData release]; 

    // inform the user 
    NSLog(@"Connection failed! Error - %@ %@", 
      [error localizedDescription], 
      [[error userInfo] objectForKey:NSErrorFailingURLStringKey]); 
} 

- (void)connectionDidFinishLoading:(NSURLConnection *)connection 
{ 
    // do something with the data 
    // receivedData is declared as a method instance elsewhere 
    NSLog(@"Succeeded! Received %d bytes of data",[receivedData length]); 

    // release the connection, and the data object 
    [connection release]; 
    [receivedData release]; 
} 

我得到didReceiveData上的EXC_BAD_ACCESS。即使該方法只包含一個NSLog,我也會得到該錯誤。

注:receivedData是NSMutableData *在我的頭文件

+0

初始化'receivedData'變量的行中的'data'是什麼? – Mark 2010-05-10 11:27:50

回答

6

使用NSZombieEnabled破發點,並檢查它是釋放對象。

同時檢查:

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response 
{ 
    if ([response expectedContentLength] < 0) 
    { 
     NSLog(@"Connection error"); 
      //here cancel your connection. 
      [connection cancel]; 
     return; 
    } 
} 
+0

殭屍斷點說:*** - [NSConcreteMutableData長度]:消息發送到釋放實例0xd4af700不知道如何診斷... – 2010-05-10 11:48:35

+0

可能在connectionDidFinishLoading方法,請嘗試從該方法中刪除代碼。如果多數民衆贊成你的receivedData變量的問題是這裏的問題... – Mark 2010-05-10 11:50:28

+0

我註釋掉了connectionDidFinishLoading中的所有代碼,並且該應用程序不再崩潰。你認爲receivedData有什麼問題? – 2010-05-10 11:54:06

2

如果你在didRecieveData得到錯誤,無論它裏面的代碼,它看起來像你的委託被釋放?

我會檢查包含getMessages方法的對象在連接完成獲取數據之前未被釋放(或自動釋放)。


編輯:下圖顯示了評論,我上面的回答是錯誤的:)

的問題是在recievedData變量 - 它被提前釋放。 Mark建議在創建連接的對象的dealloc方法中釋放它,所以他值得所有的功勞!

這裏有一點小事要注意 - 如果你在dealloc方法中釋放recievedData,如果你多次調用getMessages,將會泄漏內存。你需要稍微改變的getMessages這樣:

... 
if (theConnection) { 
    [recievedData release]; // If we've been here before, make sure it's freed. 
    receivedData = [[NSMutableData data] retain]; 
} else { 
... 
+0

另外,儘量不要在'didRecieveData'中做任何事情,也就是說,沒有代碼行,只是一個空方法,它將確定它的委託是否被釋放,而不是別的什麼 – Mark 2010-05-10 11:30:43

+0

即使didReceiveData不包含代碼行,我也會得到相同的錯誤。代表本身。 – 2010-05-10 11:34:13

+0

也對'didReceiveResponse'也做了同樣的事情,看看這是否有助於縮小問題的範圍 – Mark 2010-05-10 11:39:55

5

我按照蘋果的文檔中的準則:

這是不正確的。在兩個以下,你打破了規則:

- (void)connection:(NSURLConnection *)connection 
didFailWithError:(NSError *)error 
{ 
    // release the connection, and the data object 
    [connection release]; 
    // receivedData is declared as a method instance elsewhere 
    [receivedData release]; 

    // inform the user 
    NSLog(@"Connection failed! Error - %@ %@", 
      [error localizedDescription], 
      [[error userInfo] objectForKey:NSErrorFailingURLStringKey]); 
} 

- (void)connectionDidFinishLoading:(NSURLConnection *)connection 
{ 
    // do something with the data 
    // receivedData is declared as a method instance elsewhere 
    NSLog(@"Succeeded! Received %d bytes of data",[receivedData length]); 

    // release the connection, and the data object 
    [connection release]; 
    [receivedData release]; 
} 

在這兩種情況下,你不獲得connection對象與alloc,方法開頭new或含有copy。這些方法中您不擁有connection。你不能用這些方法釋放它。

在我看來,稍微有點不妥,你也在那裏發佈receivedData。我建議你在釋放它之後立即將實例變量設置爲零。

[receivedData release]; 
receivedData = nil; 

這樣,它不會被意外地釋放一次。

1

評論JeremyP,他在那裏說「在以下兩種情況下,你違反規則」:Sheehan Alam正在關注Apple的代碼(實際上,cut'n'paste)發現here

我還想補充(這是一些沒有很好回答here)'構建和分析'標誌NSURLConnection(它是由一個「[NSURLConnection alloc ]「)。但是如果在NSURLConnection的[連接釋放]中放入同樣的方法,它將會崩潰。

因此,我們有一些似乎違背了內存管理的「規則」,但作品(據我所知),是蘋果公司的文檔..

2

我與設備調試時雖然沒有問題得到了同樣的錯誤在模擬中。添加下面的代碼行後釋放receivedData解決了這個問題:

receivedData = nil; 
0

我在NSURLConnection的EXC_BAD_ACCESS了異步調用。 由http://www.sudzc.com

我需要添加生成的代碼保留

receivedData = [[NSMutableData data] retain];

和回調方法沒有得到壞接入信號了。

  • 如果我添加了

    if ([response expectedContentLength] < 0) { NSLog(@"Connection error"); //here cancel your connection. [connection cancel]; return; }

比我的web服務被取消,否則完美的作品。

0

雖然它沒有回答完整的問題,但我已經遇到了這個錯誤幾次,因爲我將請求的HTTPBody設置爲NSString而不是NSData。 Xcode試圖警告我。