2009-02-14 16 views

Respuesta

-2

Esto es definitivamente posible usando NSKeyValueObserving. Las propiedades en realidad tienen implementaciones getter/setter, el compilador las acaba de hacer a través de la palabra clave @synthesize en una implementación de clases Objective-C. Como el protocolo de observación de valores clave se basa en las convenciones getter/setter estándar en Objective-C, las propiedades de observación funcionan bien. La documentación (vinculado anteriormente) incluso menciona propiedades de clase por nombre:

"El NSKeyValueObserving (KVO) protocolo informal define un mecanismo que permite a los objetos para ser notificados de cambios a los especificados propiedades de otros objetos."

+0

Una propiedad de solo lectura no tiene un método setter, por lo que no se puede observar de la misma manera que una propiedad readwrite. – futurevilla216

21

Sí, es posible observar las propiedades de solo lectura. Sin embargo, si el objeto que declara que la propiedad realiza cambios en el valor de esa propiedad de una manera que no es Observación de valores-clave compliant (por ejemplo, cambia el valor de la variable de instancia que respalda dicha propiedad directamente sin incluir willChangeValueForKey: y didChangeValueForKey: notificaciones) los observadores no serán notificados automáticamente por el sistema KVO. Si puede verificar que el valor de esta propiedad está cambiando y sus observadores no están siendo notificados, (1) publicará algún código aquí o en otro lugar para que otros puedan ayudarlo a encontrar su error y (2) si no hay errores en su código, archivar un error en el radar de Apple.

+0

Buena respuesta gracias. +1 – Sabobin

+0

Esa fue la pieza que NSHipster olvidó olvidar. –

2

Sin duda, puede observar las propiedades de solo lectura, pero tenga en cuenta que para que KVO funcione debe ser compatible con KVC, lo que significa usar el setter/getter para una propiedad (ya que es de solo lectura, no obtiene un colocador gratis a través del @synthesize) o el método -setValue:forKey: de la propiedad.

15

Sí. Una forma fácil de implementarlo en su propia clase es declarar la propiedad como de solo lectura en el archivo .h y redeclararla como escribible en la interfaz privada en el archivo .m. De esta forma puede sintetizar y obtener las notificaciones de cambio manejadas automáticamente.

En el archivo .h:

@interface MyClass : NSObject 
@property (nonatomic, readonly) BOOL foo; 
@end 

En el archivo .m

@interface MyClass() 
@property (nonatomic, readwrite) BOOL foo; 
@end 

@implementation MyClass 

@synthesize foo; 

- (void)bar { 
    // Observers will see the change 
    self.foo = YES; 
} 

@end 
+0

Creo que esto no dejará de realizar 'myObject.foo = YES' desde fuera de esta clase (a menos que, quizás, ARC grite que no puede ver una declaración) – user1071136

+1

No pensé que esto funcionaría debido al choque en los métodos de sintetizar , pero parece funcionar para mí Públicamente, el método no está disponible, pero puedo configurarlo de forma privada. – jowie

+1

Esto es exactamente cómo hacer esto y, como Jowie señaló, simplemente configúralo de forma privada. Sin embargo, tenga en cuenta que si configura _foo y establece eso, entonces KVO no se activa. – Arvin

0

Una respuesta ligeramente diferente:

@interface MyClass : NSObject 
@property (nonatomic, readonly) BOOL foo; 
@end 

En el archivo .m

@interface MyClass() 
@property (nonatomic, readwrite) BOOL foo; 
@end 

@implementation MyClass 

+ (NSSet *)keyPathsForValuesAffectingFoo { 
    return [[NSSet alloc] initWithObjects:NSStringFromSelector(@selector(foo)), nil]; 
} 

@end 
Cuestiones relacionadas