2010-11-10 11 views
14

Tengo dos clases en mi aplicación de clase A y Clase B. Ambas clases A y B son instancias de UIViewController. La clase A tiene un botón que cuando se empuja empuja la clase B a la pila. La clase B tiene una cadena que la clase A desea observar y actualizar su interfaz según sea necesario. He podido usar: [self addObserver:self forKeyPath:@"name" options:0 context:NULL]; en la clase B para ver los cambios en la cadena. Cuando intento y utilizo el siguiente método en la clase A viewWillAppear:iPhone KVO entre dos clases

ClassB *b = [[ClassB alloc]init]; 
[b addObserver:self forKeyPath:@"name" options:0 context:NULL]; 

y añadir el método:

(void)observeValueForKeyPath:(NSString)keyPath ofObject:(id)object 
         change:(NSDictionary)change 
        context:(void)context 

Ninguna acción se desencadena cuando se trata de ver las actualizaciones realizadas en B de A. se siente tonto al hacer esta pregunta, pero ¿cómo funciona KVO entre dos clases en iOS? Sé que esto debería funcionar

Respuesta

38

Puede observar los cambios en diferentes objetos/clases. Creo que el problema está en el parámetro de opciones addObserver:forKeyPath:options:context:.

Existen varias opciones para el tipo de observación que desea realizar. El KVO Guide es un buen punto de partida, pero es probable que desee NSKeyValueObservingOptionNew, que utilizo en el siguiente ejemplo.

Primero, "nombre" debe ser una propiedad pública en ClassB.

En segundo lugar, probablemente no necesite agregar el observador a "b" en viewWillAppear en Clase A, porque no necesita agregarlo cada vez que aparezca la vista ClassA. Solo necesita agregar el observador una vez, cuando crea la vista ClassB. Una vez que haya agregado el observador, el método observeValueForKeyPath:ofObject:change:context: se ejecutará en Clase A, de modo que puede hacer la actualización desde allí. No debería necesitar hacer nada cada vez que ClassA esté a punto de aparecer.

En la Clase A, probablemente debería crear ClassB justo antes de empujar ClassB en la pila del controlador, presumiblemente en el controlador de eventos para alguna acción que el usuario haya tomado. Inmediatamente después de crear ClassB, agregue el observador en ClassA con el valor NSKeyValueObservingOption correcto.

Si sólo desea ser notificado cada vez que se cambia la propiedad pública "nombre" en ClassB, a continuación, intente esto:

ClassB

claseA

@interface ClassA : UIViewController { 
} 

@property (nonatomic, retain) IBOutlet UILabel* nameLabel; 

- (IBAction) someEventHandler:(id)sender; 

@end 

@implementation ClassA 

- (IBAction) someEventHandler:(id)sender { 
    ClassB* b = [[ClassB alloc]init]; 
    [b addObserver:self forKeyPath:@"name" options:NSKeyValueObservingOptionNew context:NULL]; 
    [self.navigationController pushViewController:b animated:YES]; 
    [b release]; 
} 

- (void) observeValueForKeyPath:(NSString*)keyPath ofObject:(id)object change:(NSDictionary*)change context:(void*)context { 
    if ([keyPath isEqual:@"name"]) { 
     NSString* changedName = [change objectForKey:NSKeyValueChangeNewKey]; 
     // do something with the changedName - call a method or update the UI here 
     self.nameLabel.text = changedName; 
    } 
} 

@end 
+0

Esta es probablemente la problema. Debe usar el parámetro de opciones para indicar qué notificaciones quiere. Al pasar 0, no estás pidiendo que te notifiquen nada. – benzado

+0

nekno, gracias por la ayuda! – fmcauley

+6

Si esto ayuda a alguien, tuve un problema donde mi mensaje observeValueForKeyPath no se activaba, aunque lo escribí casi exactamente igual que nekno. * TIENE * que cambiar la propiedad usando self.name = newvalue, * NOT * simplemente name = newvalue. – Mirkules

Cuestiones relacionadas