2010-10-17 22 views
7

Tengo una consulta simple que me gustaría aclarar por alguien ... ¿Es una mala práctica retenerme?¿Mala práctica para retener a "uno mismo"?

Tengo un objeto de solicitud de servidor que me gustaría hacer. Me gustaría ser capaz de utilizarlo de la siguiente manera:

ARequest *request = [ARequest request: someParam]; 
request.delegate = self; 
[request begin]; 

Para que el objeto no de autodestrucción tan pronto como se vacía la piscina autorelease, supongo que tengo que llamar a un retener en su método init y luego un lanzamiento una vez que la respuesta del servidor ha sido recibida, procesada y entregada a su delegado.

Sin embargo, algo está levantando una campana de advertencia en mi cabeza con este enfoque. ¿Mejores formas de hacerlo?

Respuesta

6

No hay nada de malo en retener self, siempre y cuando lo suelte en un punto bien definido de acuerdo con el protocolo de gestión de memoria normal. Si un objeto se requiere que exista hasta que se cumpla alguna condición, debe asumir la responsabilidad de eso, de la misma manera que lo hace para cualquier otro objeto que requiera continuar existiendo.

Introducir objetos gerentes que de otro modo serían extraños o imponer la responsabilidad al propietario del objeto por motivos supersticiosos sería el verdadero antipatrón.

(El enfoque equivalente en código de recolección de basura sería para el objeto de excluir a sí mismo de la recolección de basura, mientras que los resultados están pendientes, o la raíz a través de una colección de algún tipo si no le gusta la idea.)

1

La manera más fácil de hacer esto sería crear un iVar para su solicitud, conservar la solicitud cuando la inicie y liberarla cuando se llame al último método delegado.

¿Es ARequest una clase que ha creado? ¿Crea un nuevo hilo para enviar la solicitud de forma asíncrona?

+0

Sí, ARequest es básicamente una clase que crea un NSURLConnection para enviar una solicitud de forma asincrónica. Podría usar un ivar, pero es posible que tenga algunas solicitudes enviadas a la vez, por lo que tendría que mantener una colección de solicitudes de algún tipo. Apple parece usar un patrón que no requiere el mantenimiento de este tipo (SKProductsRequest por ejemplo) sin embargo. – Tricky

0

Una vez hice lo mismo que usted. Escribí un Category-Method en NSString para enviarlo a un servidor, que lo imprimirá. En el Método de Categoría, tuve que llamar al [self retain], para que los métodos de devolución de llamada pudieran ser un NSString-Categroy-Method a.
Me sentí tan mal por eso, que reescribí todo para usar un Singleton, al que se accede mediante el Método de Categoría. Entonces, Singleton retendrá la cadena el tiempo que sea necesario.

+0

Sí, esa es la cuestión ... Por alguna razón, se siente 'malo', pero me pregunto si realmente es así. Apple maneja esto de alguna manera en SKProductsRequest por ejemplo, pero ¿es a través de un [self retain] o mantienen una colección de solicitudes pendientes en alguna parte? – Tricky

2

No es inaudito, pero es algo poco común. La principal forma en que lo he visto usar (y lo he usado) es cuando se trata de algún tipo de objeto semioscrónico (por semi-sincrónico quiero decir que no bloquea el hilo principal, pero tampoco ejecutar en un hilo de fondo; un NSURLConnection se ajustaría a esta factura). Por ejemplo, escribí una subclase de NSWindowController que era específicamente para mostrar una ventana como una hoja y para invocar algunas devoluciones de llamada de delegado. Básicamente, tendría alloc/init un nuevo controlador de hoja e invocar beginSheetForWindow:. Esto ejecutaría la hoja de forma semisincrónica, y luego invocaría una devolución de llamada apropiada cuando se descartara la hoja.

Dado que el objeto invocado no necesariamente "posee" la hoja (piense en una versión Mac de un controlador de vista modal en iOS), el controlador de hoja hace [self retain] inmediatamente antes de mostrar la hoja y [self release] inmediatamente después de la limpieza arriba e invocar devoluciones de llamada. El propósito detrás de esto era asegurar que el objeto del controlador se quedara hasta que se completara la hoja. (La hoja, IIRC, fue retenida por el runloop, pero también necesitaba que el controlador se quedara)

Como dije, es muy raro encontrar una situación en la que desee [self retain], pero no es imposible. Sin embargo, como regla general, si cree que necesita [self retain], es posible que desee pensar de nuevo.

Cuestiones relacionadas