异步NSURLConnection引发EXC_BAD_ACCESS

时间:2010-05-10 11:22:37

标签: iphone objective-c cocoa-touch xcode nsurlconnection

我不确定为什么我的代码会抛出EXC_BAD_ACCESS,我已遵循Apple文档中的指导原则:

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

7 个答案:

答案 0 :(得分:6)

使用 NSZombieEnabled 断点并检查哪个是释放的对象。

同时检查:

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

答案 1 :(得分:5)

  

我已遵循Apple文档中的指导原则:

事实并非如此。在以下两个方面,您违反了规则:

- (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。你不能在这些方法中释放它。

我觉得你在那里发布了receiveData有点狡猾。我建议您在释放后立即将实例变量设置为nil。

[receivedData release];
receivedData = nil;

这样,它不会被意外地释放出来而不是一次。

答案 2 :(得分: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 {
...

答案 3 :(得分:2)

我在使用设备进行调试时遇到了同样的错误,尽管模拟没有问题。在释放receivedData之后添加以下代码行解决了问题:

receivedData = nil;

答案 4 :(得分:1)

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

我还想补充(这是一个没有得到很好回答的问题here),“构建和分析”标志着NSURLConnection上的“潜在泄漏”(以“ [NSURLConnection alloc]“)。但是如果在NSURLConnection上输入[theConnection release],在同一方法中它会崩溃。

所以我们有一些东西似乎违反了内存管理的“规则”,但仍有效(afaik)并且在Apple的文档中。

答案 5 :(得分: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; }

比我的所有网络服务都被取消,否则效果很好。

答案 6 :(得分:0)

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