2009-10-27 9 views
5

Al pasar un delegado a la NSUrlConnection un objeto de esta manera:¿Cuándo llamar al lanzamiento en NSURLConnection delegate?

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

cuándo se debe llamar de liberación del delegado? ¿Debería estar en connectionDidFinishLoading? Si es así, sigo recibiendo exec_bad_access. Estoy viendo que mis delegados están filtrando a través de los instrumentos.

Gracias

Respuesta

3

Dependerá de qué objeto handler es y cómo usarlo. Por ejemplo, yo suelo usar self como mi delegado:

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

No necesito llamar a la libertad bajo self porque los delegados no se conservan y self serán liberados por otro objeto.

Si handler es un objeto nuevo, entonces deberá liberarlo (y connectionDidFinishLoading: debería estar bien, a menos que necesite usar el objeto handler para otra cosa).

¿Está familiarizado con las reglas para memory management in Cocoa?

¿Puede dar una mejor idea de qué objeto es handler y cómo lo está usando?

0

Su necesidad de liberar la conexión, no el delegado. La clase NSURLConnection, creo que no retiene al delegado, que es la razón por la que obtienes un bloqueo cuando intentas liberarlo.

Los dos lugares para liberar la conexión son la conexión: DidFinishLoading, y la conexión: didFailWithError.

+0

sí, eso es lo que yo también pensaba, pero cuando hago eso ... obtengo el acceso del ejecutivo al mal acceso de los dioses que me golpean. –

+2

En realidad, estoy bastante seguro de que NSURLConnection conserva el delegado (es una excepción en este sentido). – shosti

+1

NSURLConnection retiene al delegado, verifique la documentación. –

-1

el controlador de objeto se utiliza para implementar connectionDidFinishLoading didReceiveData etc. Puedo hacer muchas llamadas a un número de servicios web y en lugar de crear un objeto para cada uno, tengo una clase central para todas esas cosas:

@interface DataService : NSObject {} 

- (void) search:(NSString *) name byAddress:(NSString *)address; 

@end 

por lo que la aplicación de dicho método crea el delegado de pasar:

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

lo que estoy viendo en instrumentos es que hay una pérdida de memoria en el SearchDelegate ... así que creo que está siendo realmente retener ' ed.

Tinkering un poco cambié de sendRequestToUrlMethod tener esto:

// http code setup blah... 

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

y esto parece haber conseguido montado de pérdida de memoria que se informa de un instrumento.

6

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


Se le tiene que prestar una atención especial al objeto delegado como, por NSURLConnection, hay una consideración especial para el delegado: siempre se conserva.

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

initWithRequest: delegar:

Consideraciones especiales: La conexión retiene delegado. Libera delegado cuando la conexión termina de cargar, falla, o se cancela.

Por lo tanto, teniendo esto en cuenta, tiene varias opciones para asegurarse de que su delegado se lanzará correctamente y trataré de explicar 2 simples.

La primera, y la más utilizada, es utilizar la misma clase que inicializa NSURLConnection como delegado.

[[NSURLConnection alloc] initWithRequest:request self]; 

Al hacer esto, la clase de la cuenta de retención se incrementa en 1 cuando la conexión se inicia y luego harían menos reducida en 1 después de la conexión termina de cargar, falla o se cancela, lo que no habría pérdidas de memoria.

La segunda opción, la que está tratando de hacer, es usar otro objeto para manejar todas las llamadas de conexión. Esto funciona bien también, pero necesitarás atención extra con la memoria. Una cosa simple que podría hacer para resolver su problema es inicializar la conexión con un objeto de liberación automática.

//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 se podía liberar su controlador justo después de la creación de la conexión (ya que será ya retenida por la conexión)

//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 formas saldrán de la propiedad de objetos controlador sólo con la conexión La clase, que liberará el objeto del controlador justo después de que termine de cargarse, falla o se cancela, una vez más, no provoca fugas de memoria.

EDIT: Al hacer cualquiera de las opciones anteriores, no tiene que preocuparse por liberar el delegado (pero aún tiene que liberar la conexión) en los métodos connection:DidFinishLoading y connection:didFailWithError.

0

NSURLConnection delegado se conserva.

Utilice 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]);