2010-05-10 18 views
6

No estoy realmente seguro de por qué mi código es lanzar una EXC_BAD_ACCESS, he seguido las instrucciones en la documentación de Apple:asíncrono NSURLConnection Lanza 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!"); 
    } 

} 

Y mi delegado métodos

#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]; 
} 

consigo un EXC_BAD_ACCESS en didReceiveData. Incluso si ese método simplemente contiene un NSLog, obtengo el error.

Nota: receivedData es un NSMutableData * en mi archivo de cabecera

+0

¿Qué significa 'datos' en la línea que inicializa su variable 'receivedData'? – Mark

Respuesta

6

Uso NSZombieEnabled punto de quiebre y comprobar que es el objeto liberado.

También puedes ver:

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

Punto de interrupción zombie dice: *** - [NSConcreteMutableData length]: mensaje enviado a la instancia desasignada 0xd4af700 no está seguro de cómo diagnosticar ... –

+0

que podría estar en el método connectionDidFinishLoading, intente eliminar el código de ese método también.si ese es el problema aquí es la variable recibidaData ... – Mark

+0

Comente todo el código en connectionDidFinishLoading, y la aplicación no se cuelga más. ¿Qué crees que está mal con receivedData? –

2

Si usted está recibiendo el error en didRecieveData independientemente del código dentro de él, parece que su delegado ha sido liberado?

Compruebo que el objeto que contiene el método getMessages no se está lanzando (o se ha lanzado automáticamente) antes de que la conexión haya terminado de obtener datos.


EDIT: Los comentarios a continuación muestran que mi respuesta anterior está mal :)

El problema estaba en la variable recievedData - que estaba siendo puesto en libertad antes de tiempo. Mark sugiere liberarlo en el método dealloc del objeto que crea la conexión, ¡así que merece todo el crédito por esto!

Hay una pequeña cosa a tener en cuenta: si libera recievedData en el método dealloc, perderá memoria si llama a getMessages más de una vez. Usted tendrá que cambiar ligeramente getMessages a esto:

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

Además, trate de no hacer nada en el 'didRecieveData', es decir, no líneas de código, solo un método vacío, que determinará si es el delegado liberado y no otra cosa – Mark

+0

incluso si didReceiveData no contiene líneas de código, obtengo el mismo error. El delegado es en si mismo –

+0

haga lo mismo con 'didReceiveResponse' también, vea si eso ayuda en absoluto a reducir el problema – Mark

5

He seguido las instrucciones en la documentación de Apple:

Eso no es cierto. En ambos de los siguientes, a romper las reglas:

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

En ambos casos, no lo hace obtener el objeto connection con alloc, un método que comienza con new o que contengan copy. No posee connection en estos métodos. No debes liberarlo en estos métodos.

Me parece un poco dudoso que esté liberando datos recibidos allí también. Le sugiero que establezca inmediatamente la variable de instancia en cero después de que la libere.

[receivedData release]; 
receivedData = nil; 

De esta forma, no se liberará accidentalmente más de una vez.

1

Comentando sobre JeremyP, donde dice que "En ambos de los siguientes, usted rompe las reglas": Sheehan Alam sigue el código de Apple (en realidad, cut'n'paste) encontró here.

También me gustaría agregar (y esto es algo que no fue bien respondido here) que el 'construir y analizar' marca una "fuga potencial" en la NSURLConnection (que se inicia con una "[NSURLConnection alloc ] "). Pero si uno pone un [lanzamiento de conexión] en NSURLConnection, en el mismo método, se bloqueará.

Así que tenemos algo que parece desafiar las 'reglas' para la gestión de memoria, sin embargo, las obras (que yo sepa) y se encuentra en la documentación de Apple ..

2

me dieron el mismo error al depurar con el dispositivo, aunque no había ningún problema en simulación Añadiendo la siguiente línea de código después de soltar receivedData resolvió el problema:

receivedData = nil; 
0

llegué EXC_BAD_ACCESS en llamada asincrónica en NSURLConnection. El código es generado por http://www.sudzc.com

que necesitaba para añadir un retener a

receivedData = [[NSMutableData data] retain];

y los métodos de devolución de llamada no recibe señal de acceso mal nunca más.

  • si añado el

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

que todos mis servicios web se cancelan, por lo demás funciona perfectamente.

0

Si bien no responde la pregunta completa, me he encontrado con este error un par de veces porque establecí el HTTPBody de la solicitud en un NSString en lugar de un NSData. Xcode intentó advertirme.