Pregunta

Tengo una pregunta sobre las variables de instancias en combinación con bloques y arco en el objetivo C con iOS5.

En breve, cuando accedo a este código, el iPhone me da un exc_bad_access y termina:

- (void) doRequest: (void (^)(XMLTreeNode*) )completionHandler {
    NSString * urlString = [NSString stringWithFormat:@"blablaurl=%@&", action];

    for( NSString* key in parameters ){
        urlString = [urlString stringByAppendingFormat:@"&%@=%@", key, [parameters objectForKey:key]];
    }
    NSURL * url = [NSURL URLWithString:urlString];

    NSLog( @"Visiting: %@", [url absoluteString] );

    NSMutableURLRequest * request = [NSMutableURLRequest requestWithURL:url];
    [request setHTTPMethod:@"GET"];

    [NSURLConnection sendAsynchronousRequest:request queue:[[NSOperationQueue alloc] init] completionHandler:^(NSURLResponse * response, NSData * data, NSError * err) {
            NSLog( @"Params=%@", parameters );
        completionHandler(e);
    }];
}

El exc_bad_access ocurre en: nslog ( @"params =% @", parámetros);

(Parámetros es una variable de instancia de la clase). Acaba de definir en el archivo de encabezado, sin propiedad especial o lo que sea.

¿Por qué se bloquea y cómo puedo prevenirlo? ¡Gracias!

Supongo que se bloquea porque la vida útil de los objetos ha terminado después de la llamada de Dorequest, y por lo tanto ARC limpia todas ..

¿Fue útil?

Solución

Los parámetros están limpios por ARC.

2 Caso aquí:

Su objeto principal no se libera antes de la finalización del bloque: simplemente cree una propiedad sólida y no atómica para "parámetros". Usando la palabra clave "fuerte" en su propiedad, le diga a ARC que necesita "parámetros" durante toda su vida de objeto principal

Su objeto principal se libera antes de la finalización del bloque: cree un nuevo puntero __block a su objeto

__block blockParameters = parameters;
[NSURLConnection sendAsynchronousRequest:request queue:[[NSOperationQueue alloc] init] completionHandler:^(NSURLResponse * response, NSData * data, NSError * err) {
    NSLog( @"Params=%@", blockParameters );
    completionHandler(e);
}];

Usando la palabra clave "__block", diga al arco que necesita "blockparameters" durante toda su vida de bloque

Otros consejos

Solo tienes los parámetros del bloque a tu disposición, es decir response, data y error en este caso. Podrías usar [response URL] para llegar a los parámetros.

NSString *path = [[response URL] path];
NSString *secondPartOfURL = [[path componentsSeparatedByString:@"?"] objectAtIndex:1];
NSArray *keyValuePairs = [secondPartOfURL componentsSeparatedByString@´:@"&"];
NSMutableDictionary *parameters = [NSMutableDictionary dictionary];
for (NSString *pair in keyValuePairs) {
   NSArray *keyValue = [pair componentsSeparatedByString:@"="];
   [parameters setValue:[keyValue objectAtIndex:1] 
                 forKey:[keyValue objectAtIndex:0]];
}
NSLog(@"Params=%@", parameters);
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top