objective-c ios automatic-ref-counting

objective c - ¿Establezco propiedades en nulo en dealloc cuando uso ARC?



objective-c ios (2)

Estoy tratando de aprender el conteo automático de referencias en iOS 5. Ahora la primera parte de esta pregunta debería ser fácil:

  1. ¿Es correcto que NO necesito escribir declaraciones explícitas de propiedad de liberación en mi dealloc cuando uso ARC? En otras palabras, ¿es cierto que lo siguiente NO necesita un trato explícito?

    @interface MyClass : NSObject @property (strong, nonatomic) NSObject* myProperty; @end @implementation MyClass @synthesize myProperty; @end

  2. Mi siguiente y más importante pregunta proviene de una línea en el documento de Notas de publicación de Transitioning to ARC :

    No tiene que (de hecho no puede) liberar variables de instancia, pero puede necesitar invocar [self setDelegate: nil] en las clases del sistema y otro código que no se compila con ARC.

    Esto plantea la pregunta: ¿cómo sé qué clases del sistema no se compilan con ARC? ¿Cuándo debería crear mi propio dealloc y establecer de forma explícita fuertes propiedades de retención en nil? ¿Debería suponer que todas las clases de marcos de NS y UI utilizadas en propiedades requieren explícitamente desglose?

Hay una gran cantidad de información sobre SO y en otras partes sobre las prácticas de liberar el respaldo de una propiedad cuando se utiliza el seguimiento de referencia manual, pero relativamente poco acerca de esto cuando se utiliza ARC.


Solo para dar la respuesta opuesta ...

Respuesta corta : no, no tiene que dealloc propiedades de sintetización automática en dealloc en ARC. Y no tienes que usar el setter para aquellos en init .

Respuesta larga : Debería dealloc propiedades de sintetización personalizada en dealloc , incluso bajo ARC. Y deberías usar el setter para aquellos en init .

El punto es que sus propiedades sintetizadas a medida deben ser seguras y simétricas con respecto a la anulación.

Un posible colocador para un temporizador:

-(void)setTimer:(NSTimer *)timer { if (timer == _timer) return; [timer retain]; [_timer invalidate]; [_timer release]; _timer = timer; [_timer fire]; }

Un posible setter para scrollview, tableview, webview, textfield, ...:

-(void)setScrollView:(UIScrollView *)scrollView { if (scrollView == _scrollView) return; [scrollView retain]; [_scrollView setDelegate:nil]; [_scrollView release]; _scrollView = scrollView; [_scrollView setDelegate:self]; }

Un posible colocador para una propiedad de KVO:

-(void)setButton:(UIButton *)button { if (button == _button) return; [button retain]; [_button removeObserver:self forKeyPath:@"tintColor"]; [_button release]; _button = button; [_button addObserver:self forKeyPath:@"tintColor" options:(NSKeyValueObservingOptions)0 context:NULL]; }

Entonces no tiene que duplicar ningún código para dealloc , didReceiveMemoryWarning , viewDidUnload , ... y su propiedad puede hacerse pública de forma segura. Si estaba preocupado por las propiedades de nulo en dealloc , entonces podría ser hora de que vuelva a verificar sus setters.


Respuesta corta : no, no tiene que dealloc propiedades en dealloc bajo ARC.

Respuesta larga : nunca debe dealloc propiedades en dealloc , incluso en la gestión manual de la memoria.

En MRR, deberías liberar tus ivars . Nilling out properties significa llamar a los setters, que pueden invocar un código que no debe tocar en dealloc (por ejemplo, si su clase, o una subclase, anula al setter). Del mismo modo, puede activar las notificaciones de KVO. Liberar el ivar evita en cambio estos comportamientos no deseados.

En ARC, el sistema libera automáticamente cualquier ivars por ti, así que si eso es todo lo que estás haciendo, ni siquiera tienes que implementar dealloc . Sin embargo, si tiene ivars no objeto que necesitan un manejo especial (por ejemplo, búferes asignados que necesita free() ) todavía tiene que lidiar con aquellos en dealloc .

Además, si se ha establecido como el delegado de cualquier objeto, debe dealloc configuración de esa relación en dealloc (esta es la [obj setDelegate:nil] llamar [obj setDelegate:nil] ). La nota sobre hacer esto en clases que no están compiladas con ARC es un guiño a las propiedades débiles. Si la clase marca explícitamente su propiedad de delegate como weak entonces no tiene que hacer esto, porque la naturaleza de las propiedades débiles significa que se agotará para usted. Sin embargo, si la propiedad está marcada como dealloc , debe dealloc en su dealloc , de lo contrario la clase quedará con un puntero colgando y probablemente se bloqueará si intenta dealloc un mensaje a su delegado. Tenga en cuenta que esto solo se aplica a las relaciones no retenidas, como los delegados.