两类之间的iPhone KVO

我在我的应用程序类A和类B中有两个类。类A和B都是UIViewController的实例。 类A有一个button,当按下时将类B推入堆栈。 B类有一个string,类A想要观察并根据需要更新它的接口。 我已经能够使用: [self addObserver:self forKeyPath:@"name" options:0 context:NULL]; 在类B中查看对string的更改。 当我尝试在类viewWillAppear方法中使用以下内容:

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

并添加方法:

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

当试图从A中查看B中所做的更新时,没有任何操作被触发。我觉得这个问题很愚蠢,但是如何在iOS中的两个类之间工作? 我知道这应该工作。

您可以观察不同对象/类中的更改。 我认为问题是在addObserver:forKeyPath:options:context:的选项参数addObserver:forKeyPath:options:context:

您想要进行的观测types有多种select。 KVO指南是一个很好的起点,但是您可能需要NSKeyValueObservingOptionNew ,我在下面的示例中使用它。

首先,“名称”应该是ClassB中的公共财产。

其次,您可能不需要将观察者添加到ClassA中的viewWillAppear中的“b”,因为每次ClassA视图出现时都不需要添加它。 当您创buildClassB视图时,您只需要添加一次观察者。 一旦添加了观察者, observeValueForKeyPath:ofObject:change:context:方法将在ClassA中执行,因此您可以从ClassA UI执行更新。 每次ClassA即将出现时,您都不需要做任何事情。

在A类中,您应该在将ClassB推送到控制器堆栈之前创buildClassB,推测可能是在事件处理程序中用户执行了某些操作。 在创buildClassB之后,立即在ClassA中添加具有正确的NSKeyValueObservingOption值的观察者。

如果您只是想在ClassB中的公共属性“名称”发生更改时收到通知,请尝试以下操作:

ClassB的

 @interface ClassB : UIViewController { } @property (retain) NSString* name; - (void) aMethodThatModifiesName:(NSString*)newName; @end @implementation ClassB @synthesize name; - (void) aMethodThatModifiesName:(NSString*)newName { // do some stuff self.name = newName; } @end 

ClassA的

 @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