异步NSURLConnection的抛出EXC_BAD_ACCESS

异步NSURLConnection的抛出EXC_BAD_ACCESS

问题描述:

我真的不知道为什么我的代码抛出一个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

使用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

如果你在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

我按照苹果的文档中的准则:

这是不正确的。在两个以下,你打破了规则:

- (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; 

这样,它不会被意外地释放一次。

评论JeremyP,他在那里说“在以下两种情况下,你违反规则”:Sheehan Alam正在关注Apple的代码(实际上,cut'n'paste)发现here

我还想补充(这是一些没有很好回答here)'构建和分析'标志NSURLConnection(它是由一个“[NSURLConnection alloc ]“)。但是如果在NSURLConnection的[连接释放]中放入同样的方法,它将会崩溃。

因此,我们有一些似乎违背了内存管理的“规则”,但作品(据我所知),是苹果公司的文档..

我与设备调试时虽然没有问题得到了同样的错误在模拟中。添加下面的代码行后释放receivedData解决了这个问题:

receivedData = nil; 

我在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服务被取消,否则完美的作品。

虽然它没有回答完整的问题,但我已经遇到了这个错误几次,因为我将请求的HTTPBody设置为NSString而不是NSData。 Xcode试图警告我。