2011-12-28 14 views
6

Utilizando la nueva API TWRequest de iOS 5, me encontré con un muro de ladrillos relacionado con el uso de bloques.Uso de bloques dentro de bloques en Objective-C: EXC_BAD_ACCESS

Lo que tengo que hacer es que al recibir una respuesta exitosa a una primera solicitud, dispare inmediatamente otra. En el bloque de finalización de la segunda solicitud, notifico el éxito o el fracaso de la operación de múltiples pasos.

Aquí es más o menos lo que estoy haciendo:

- (void)doRequests 
{ 
    TWRequest* firstRequest = [self createFirstRequest]; 
    [firstRequest performRequestWithHandler:^(NSData* responseData, 
               NSHTTPURLResponse* response, 
               NSError* error) { 
     // Error handling hidden for the sake of brevity... 
     TWRequest* secondRequest = [self createSecondRequest]; 
     [secondRequest performRequestWithHandler:^(NSData* a, 
                NSHTTPURLResponse* b, 
                NSError* c) { 
      // Notify of success or failure - never reaches this far 
     }]; 
    }]; 
} 

Yo no soy de retención cualquiera de las solicitudes o mantener una referencia a ellos en cualquier lugar; es solo fuego y olvidar.

Sin embargo, cuando ejecuto la aplicación, se estrella con EXC_BAD_ACCESS en:

[secondRequest performRequestWithHandler:...]; 

Se ejecuta la primera solicitud muy bien, pero cuando trato de poner en marcha una segunda con un controlador, que se estrelle. ¿Qué pasa con ese código?


Los métodos para crear las solicitudes son tan simples como:

- (TWRequest*)createFirstRequest 
{ 
    NSString* target = @"https://api.twitter.com/1/statuses/home_timeline.json"; 
    NSURL* url   = [NSURL URLWithString:target]; 
    TWRequest* request = [[TWRequest alloc] 
          initWithURL:url parameters:params 
          requestMethod:TWRequestMethodGET]; 
    // _twitterAccount is the backing ivar for property 'twitterAccount', 
    // a strong & nonatomic property of type ACAccount* 
    request.account = _twitterAccount; 

    return request; 
} 
+0

publique el código de 'createFirstRequest' y' createSecondRequest' – vikingosegundo

+0

¿Puede publicar el código para '-createSecondRequest'? Supongo que hay un problema con este código que se ejecuta en un hilo de fondo ya que nunca hay una garantía sobre qué hilo ejecutará un controlador de finalización. –

+0

Hecho; lo siento por eso, no pensé que sería relevante. – biasedbit

Respuesta

18

Asegúrese de mantener una referencia/retención del ACAccountStore que posee el ACAccount que está utilizando para firmar el TWRequest s.

Si no lo hace, el ACAccount se volverá inválido y luego obtendrá EXC_BAD_ACCESS cuando intente disparar un TWRequest firmado con él.

+0

¡Gracias! Pero se siente un poco incómodo. Debe guardar una referencia a un objeto que no va a establecer en el objeto Solicitud de Twitter. Muy propenso a errores. – HyLian

+0

¡Guau, gracias por señalar eso! – cleverbit

+0

esto me salvó la vida – vangoz

1

No estoy familiarizado con TW *, así que considere esto una conjetura salvaje ... intentar el envío de un bloque del montón asignados :

[firstRequest performRequestWithHandler:[^ (NSData *responseData, ...) { 
    ... 
} copy]]; 

Para aclarar, yo creo el bloque que está enviando es en heap asignado, así que mientras TW * podría retenerlo, no hará ninguna diferencia si ya ha salido de s capa pluvial.

+0

resolví mi pro usando esto ya que estoy usando el arco así que retener no es más ... – GameLoading