Я не действительно уверен, почему мой код бросает 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];
}
Я получаю EXC_BAD_ACCESS на didReceiveData. Даже если тот метод просто содержит NSLog, я получаю ошибку.
Примечание: receivedData является NSMutableData* в моем заголовочном файле
Используйте NSZombieEnabled точку останова и проверьте, какой объект освобожден.
Также проверьте:
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
if ([response expectedContentLength] < 0)
{
NSLog(@"Connection error");
//here cancel your connection.
[connection cancel];
return;
}
}
Я следовал рекомендациям в документации 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];
}
В обоих случаях вы не получаете объект соединение
с помощью alloc
, метода, начинающегося с новый
или содержащий копию
. В этих методах вам не принадлежит соединение
. Вы не должны выпускать его этими методами.
Мне кажется немного изворотливым, что вы также публикуете здесь ReceiveData. Я предлагаю вам сразу же установить для переменной экземпляра значение nil после того, как вы ее отпустите.
[receivedData release];
receivedData = nil;
Таким образом, он не будет выпущен случайно больше одного раза.
Если вы получаете ошибку на didRecieveData независимо от кода внутри него, похоже, что ваш делегат был освобожден?
Я бы проверил, что объект, содержащий метод getMessages, не был освобожден (или автоосвобожден) до того, как соединение завершило получение данных.
EDIT: Комментарии ниже показывают, что мой ответ неверен :)
Проблема была в переменной recievedData - она освобождалась раньше времени. Марк предложил освобождать ее в методе dealloc объекта, создающего соединение, так что это его заслуга!
Здесь есть один нюанс - если вы освободите recievedData в методе dealloc, то при вызове getMessages более одного раза произойдет утечка памяти. Вам нужно будет немного изменить getMessages следующим образом :
...
if (theConnection) {
[recievedData release]; // If we've been here before, make sure it's freed.
receivedData = [[NSMutableData data] retain];
} else {
...