2009-07-09 7 views
23

Resumen de mi pregunta: ¿NSURLConnection conserva su delegado?¿Tiene un NSURLConnection conservar su delegado?

pregunta detallada y escenario:

que tienen una clase personalizada, llamada JsonDownloader que se toma en una URL y devuelve un NSDictionary del JSON que los rendimientos de URL.

En una aplicación de iPhone, hago algo como esto. (El método init inicia todo el proceso)

- (void)viewDidLoad { 
    JsonDownloder *temp = [[[JsonDownloader alloc] initWithURL:urlString returnDataTo:self]]; 
    [temp release]; 
    [super viewDidLoad]; 
} 

Cuando el JsonDownloader se realiza la descarga y el análisis, se realiza una devolución de llamada al returnDataTo: objeto, en este caso, el objeto que llama.

Esto funciona bien. Incluso si presento un retraso de 30 segundos en la respuesta de mi servidor web, el JsonDownloader aún existe y su devolución de llamada es correcta.

Así que mi pregunta es esta: ¿Qué es lo que mantiene JsonDownloader más allá del final del ciclo de eventos? Lo estoy liberando explícitamente.

Mi corazonada es que NSURLConnection debe retener en su delegado, pero no vi nada en la documentación. Alguien tiene ideas?

Respuesta

25

No hay muchos reguladores que no copien o retengan una variable que se le pasa, para que la memoria de dicha variable no se vuelva a asignar a otra cosa cuando su conteo de retención llegue a cero.

Sin embargo, la respuesta es SÍ, lo hace. Un poco de código de prueba muestra retener el recuento del delegado subir:

NSLog(@"Retain count before: %d", [self retainCount]); 
NSURLRequest* request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://google.com"]]; 
NSURLConnection* conn = [NSURLConnection connectionWithRequest:request delegate:self]; 
NSLog(@"Retain count after: %d", [self retainCount]); 

que produce en el registro:

Running… 
2009-07-09 02:13:40.516 delegateRetain[45123:a0f] Retain count before: 1 
2009-07-09 02:13:40.525 delegateRetain[45123:a0f] Retain count after: 2 

Debugger stopped. 

Así se puede ver muy claramente que en connectionWithRequest:delegate: "auto" es de hecho tiene su retener el recuento aumentado +1. Si te sientes valiente y quiere meterse con los dioses EXC_BAD_ACCESS, añadir en

[conn dealloc]; 
NSLog(@"Retain count after dealloc: %d", [self retainCount]); 

que se imprima "1" de nuevo, mostrando un decremento posterior dealloc. Sin embargo, obtendrá un buen Program received signal: “EXC_BAD_ACCESS”. porque el NSAutoreleasePool a tratar de liberar la conexión y se ha ido;)

+1

Gran pregunta y gran respuesta. Estaba luchando con esto yo mismo, pero decidí agregar [auto-lanzamiento] justo después de que el delegado asignara para igualar el conteo retenido. Como el yo es delegado en mi clase, no vi ninguna razón para aumentar su conteo de retenciones. Si eso es incorrecto, alguien hágamelo saber. – jocull

+0

Solo quiero agregar, gracias. The Missing Manual, parte 327. Merece la creencia de que este hecho relativamente importante no se menciona en la documentación de Apple. Pensé que lo estaba reteniendo pero no estaba seguro, los documentos no dicen nada al respecto, y en muchos casos sino en la mayoría de los casos, los delegados en los marcos de Cocoa * * no se retienen. Esta es la excepción. – n13

9

mayoría delegado propiedades no se conservan, pero asignados para evitar referencias circulares. Ver this pregunta sobre eso también.

Sin embargo, NSUrlConnection no tiene una propiedad de delegado específica. Debe especificar el delegado junto con la inicialización de la conexión. Creo que es por eso que recibe un retener, como demostró Dave Martorana.

Cuestiones relacionadas