¿Cuándo llamar al lanzamiento en el delegado de NSURLConnection?

Al pasar un delegado al object a NSUrlConnection así:

 [[NSURLConnection alloc] initWithRequest:request delegate:handler]; 

¿Cuándo debería llamar al lanzamiento del delegado? ¿Debería estar en connectionDidFinishLoading ? Si es así, sigo recibiendo exec_bad_access . Estoy viendo que mis delegates están filtrando a través de los instrumentos.

Gracias

Tomado de mi blog aquí: http://i.ndigo.com.br/2012/01/releasing-nsurlconnection-and-its-delegate/


Tendrá que prestar especial atención al object delegado ya que, para NSURLConnection , hay una consideración especial para el delegado: siempre se retiene.

http://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/NSURLConnection_Class/Reference/Reference.html#//apple_ref/doc/uid/20001697-BAJDDIDG

initWithRequest: delegado :

Consideraciones especiales : la connection se queda delegada. Libera delegado cuando la connection finaliza la carga, falla o se cancela.

Entonces, teniendo esto en count, tiene varias opciones para garantizar que su delegado sea lanzado correctamente y trataré de explicar 2 simples.

El primero y más comúnmente utilizado es usar la misma class que inicializa la NSURLConnection como el delegado.

 [[NSURLConnection alloc] initWithRequest:request self]; 

Al hacer eso, su class el recuento de retención se incrementaría en 1 cuando se inicia la connection y luego se networkinguciría en 1 después de que la connection termine de cargarse, fallar o se cancele, lo que provocará que no haya pérdidas de memory.

La segunda opción, la que está tratando de hacer, es usar otro object para manejar todas las llamadas de connection. Esto funciona bien también, pero necesitarás atención adicional con la memory. Una cosa simple que puede hacer para resolver su problema es inicializar la connection con un object de autorelease.

 //creates the handler object MyHandlerClass *handler = [[MyHandlerClass alloc] init]; //creates the connection with handler as an autorelease object [[NSURLConnection alloc] initWithRequest:request delegate:[handler autorelease]]; 

O podría liberar su manejador justo después de crear la connection (ya que la connection ya retendrá)

 //creates the handler object MyHandlerClass *handler = [[MyHandlerClass alloc] init]; //creates the connection with handler [[NSURLConnection alloc] initWithRequest:request delegate:handler]; //releases handler object [handler release]; 

Ambas forms dejarán la propiedad del object del controller solo con la class de connection, que liberará el object del controller justo después de que termine de cargarse, falle o se cancele, lo que una vez más no generará pérdidas de memory.

EDIT: Al hacer cualquiera de las opciones anteriores no tiene que preocuparse por liberar al delegado (pero aún tiene que liberar la connection) en connection:DidFinishLoading y connection:didFailWithError methods connection:didFailWithError .

Dependerá de qué handler objects sea y cómo lo use. Por ejemplo, suelo usar self como mi delegado:

[[NSURLConnection alloc] initWithRequest:request delegate:self];

No necesito llamar a release on self porque los delegates no se retienen y otro object libera a uno mismo.

Si el handler es un object nuevo, entonces deberá liberarlo (y la connectionDidFinishLoading: debe estar bien, a less que necesite usar el object handler para otra cosa).

¿Estás familiarizado con las reglas para la gestión de memory en Cocoa ?

¿Puedes dar una mejor idea de qué es el handler objects y cómo lo estás usando?

Su necesidad de liberar la connection, no el delegado. La class NSURLConnection creo que no retiene al delegado, por lo que se bloquea cuando intenta liberarlo.

Los dos lugares para liberar la connection son connection: DidFinishLoading y connection: didFailWithError.

NSURLConnection delegado de NSURLConnection se retiene.

Use el código en ViewDidLoad con un entorno que no sea ARC.

 NSLog(@"Retain count %d",[self retainCount]); NSURLConnection *con = [[NSURLConnection alloc] initWithRequest:nil delegate:self]; NSLog(@"Retain count %d",[self retainCount]); 

el manejador de objects se usa para implementar connectionDidFinishLoading didReceiveData etc. Hago muchas llamadas a varios web services y en lugar de crear un object para cada uno, tengo una class central para todo eso:

 @interface DataService : NSObject {} - (void) search:(NSString *) name byAddress:(NSString *)address; @end 

por lo que la implementación de ese método crea el delegado para que pase:

 SearchDelegate *delegate = [[SearchDelegate alloc] init]; [self sendRequestToUrl:urlString withJson:jsonString andHandler:delegate]; 

lo que estoy viendo en Instruments es que hay una pérdida de memory en SearchDelegate … así que creo que en realidad se está reteniendo.

Cambiando un poco, cambié mi sendRequestToUrlMethod para tener esto:

 // http code setup blah... [[NSURLConnection alloc] initWithRequest:request delegate:handler]; [handler release]; 

y esto parece haber sido ridiculizado por la pérdida de memory que se informa en Instruments.