2009-08-09 14 views
5

En cacao, addObserver:forKeyPath:options:context: conserva "ni el receptor, ni anObserver". Por lo tanto, supongo que la observación de uno mismo está permitida; es decir, es perfectamente válido para hacer algo comoYo observador en Cocoa

[self addObserver:self forKeyPath...]

Como siempre que se recuerde para anular el registro self como observador como la primera cosa en dealloc.

¿Es correcta esta suposición?

Respuesta

12

Sí, en realidad no hay ninguna razón por la que no se puede observar uno mismo. Pero como dijiste, como cualquier observación de KVO, asegúrate de retirarte como observador antes de desalojarlo.

Para el registro, una forma alternativa de hacer esto si usted está hablando de una simple llave es escribir un regulador de encargo y ejecutar cualquier código que necesita en la incubadora. Este estilo hace que sea un poco más obvio cuáles son los efectos completos de llamar al colocador. Sin embargo, el método KVO es un poco más flexible y funciona con rutas clave que contienen múltiples componentes.

1

hago lo que dijo Brian Webster. He aquí un ejemplo:

//.h 
... 
@property(readwrite, retain, setter=setMyPropertySynth:) id myProperty; 
-(void)setMyProperty:(id)newValue; 
.... 


//.m 
... 
@synthesize myProperty; 

-(void)setMyProperty:(id)newValue 
{ 
    //add code here 

    [self setMyPropertySynth:newValue]; 

    //add more code here 
} 
... 
+0

Esto no es una buena idea. Generalmente se espera que 'obj.foo = bar;' sea equivalente a '[obj setFoo: bar];' y desviarse de este patrón confundirá a otros que están leyendo/manteniendo su código – rpetrich

+0

@rpetrich Estoy de acuerdo en que esto no es así. una buena idea (escribí esa respuesta hace más de 18 meses), pero por una razón diferente. Ya no usaría '@ synthesize'; Ahora escribiría todo el getter y setter. La carga adicional de algunas líneas adicionales supera el costo de seguir mentalmente las llamadas al método extra (todavía utilizaría '@ property'). No estoy de acuerdo en que los efectos secundarios en setters (o getters) sean intrínsecamente malos. Deben evitarse cuando sea posible. Por ejemplo, establecer 'hypotheticalQueryObject.maxResults = 4;' podría activar legítimamente otra búsqueda. –

+0

@rpetrich Eso en realidad está garantizado. 'obj.foo = bar;' siempre utiliza cualquier implementación de 'setFoo:' que se proporciona (incluso si ha redefinido una sintetizada). –

-1

No retire observador en -dealloc. ¿Por qué? Porque cuando enciendes al recolector de basura, las cosas dejarán de funcionar; -dealloc nunca se llama. Usted sólo debe utilizar los métodos -dealloc y -finalizede código limpieza relacionado con la memoria.

+0

Buen punto; pero, ¿qué uso en su lugar, entonces? –

+0

Simplemente configúralo como parte del ciclo de vida del objeto. Si lo que lo crea le dice qué observar, y cuándo dejar de observarlo, está inyectando dependencias, lo que hace que su objeto sea más fácil de reutilizar y probar. –

+3

... pero es mucho más fácil de usar incorrectamente y socava la administración de la memoria Cocoa. Si cada creador también debe saber que el objeto creado debe ser un observador de tal o cual (particularmente si es el mismo), hemos movido la información privada a la persona que llama, lo que es malo. Peor aún, si necesito un método para "destruirlo ahora" que deshaga esta observación, entonces todo el tema de GC se fue por la ventana. La mejor solución que tenemos es duplicar las piezas de gestión que no son de memoria en dealloc y finalizar (posiblemente, elevar a una rutina compartida). Esto incluye NSNotificationCenter removeObserver también. –