2012-10-01 11 views
10

¿Es posible agregar un observador para recibir notificaciones si se modifica alguna de las propiedades del objeto supervisado? Por ejemplo:KVO para propiedades de objetos enteros

@interface OtherObject : NSObject 

@property (nonatomic) MyObject* myObject; 

@end 

y

@interface MyObject : NSObject 

@property (nonatomic) unsigned int property1; 
@property (nonatomic) unsigned int property2; 

@end 

me gustaría hacer algo como:

[otherObject addObserver:self 
       forKeyPath:@"myObject" 
        options:0 
        context:nil] 

y recibir una notificación si se modifica o bien propiedad1 o propiedad2. No parece funcionar si registro el objeto de espera (de alguna manera tiene sentido porque myObject no se modifica realmente cuando modifico property1 por ejemplo).

Respuesta

12

Puedo pensar en dos opciones.

  • Puede crear una propiedad "maestra" separada y hacerla depender de todas sus otras propiedades.

    @interface MyObject : NSObject 
    @property (nonatomic) id masterProperty; 
    @property (nonatomic) unsigned int property1; 
    @property (nonatomic) unsigned int property2; 
    @end 
    

    + (NSSet *)keyPathsForValuesAffectingMasterProperty { 
        return [NSSet setWithObjects:@"property1", @"property2", nil]; 
    } 
    

    Si observa masterProperty se le notificará cuando alguna de las propiedades cambian.

  • Utiliza el tiempo de ejecución de Objective-C para obtener una lista de todas las propiedades y observarlas todas.

    - (void)addObserverForAllProperties:(NSObject *)observer 
              options:(NSKeyValueObservingOptions)options 
              context:(void *)context { 
        unsigned int count; 
        objc_property_t *properties = class_copyPropertyList([self class], &count); 
        for (size_t i = 0; i < count; ++i) { 
         NSString *key = [NSString stringWithCString:property_getName(properties[i])]; 
         [self addObserver:observer forKeyPath:key 
            options:options context:context]; 
        } 
        free(properties); 
    } 
    
+0

Es de suponer que también podría combinar esos dos enfoques, utilizando el tiempo de ejecución de Objective-C para obtener una lista de todas las propiedades en keyPathsForValuesAffectingMasterProperty, y luego devolverlos en un NSSet. (Puede ser una buena idea usar una variable estática para que solo tenga que hacerlo una vez). – dgatwood

2

Lo que podría hacer es tener una función para modificar una propiedad particular de la myObject ...

-(void)setMyObjectName:(NSString*)name; 

y luego en la función tiene este código ...

- (void)setMyObjectName:(NSString*)name 
{ 
    [self willChangeValueForKey:@"myObject"]; 

    myObject.name = name; 

    [self didChangeValueForKey:@"myObject"]; 
} 

Esta voluntad luego, notifique al observador cuando se cambie esa propiedad en myObject.

Cuando lo necesite, utilice este patrón y podrá recibir notificaciones sobre cualquier cambio en myObject.

:: :: editar Dicho esto, usted debe ser capaz de utilizar ...

[otherObject addObserver:self 
       forKeyPath:@"myObject.property1" 
       options:0 
       context:nil]; 

y que va a observar propiedad1 y hacer lo mismo fortaleza las otras propiedades.

Pero esto significará agregar un observador para cada propiedad individualmente.

+0

Tal vez en lugar de willChangeValueForKey willChangeObjectForKey? – Andy

+1

@Andy changed. Sorprendido que no fue visto durante dos años sin embargo. jaja! – Fogmeister

Cuestiones relacionadas