2010-11-10 20 views
14

我在我的應用程序類A和類B中有兩個類。類A和B都是UIViewController的實例。類A有一個按鈕,當按下時將類B推入堆棧。 B類有一個字符串,類A想要根據需要觀察和更新它的接口。我已經能夠在B類中使用: [self addObserver:self forKeyPath:@"name" options:0 context:NULL];來查看對字符串的更改。 當我嘗試使用下面的A類viewWillAppear中方法:兩類之間的iPhone KVO

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製備的更新時,無需任何操作觸發我感覺愚蠢的問這個問題,但是KVO如何在iOS中的兩個類之間工作?我知道這應該工作。

回答

38

您可以觀察跨越不同對象/類的更改。我認爲問題出在addObserver:forKeyPath:options:context:的選項參數中。

您想要進行的觀察類型有多種選擇。 KVO Guide是一個很好的起點,但您可能需要NSKeyValueObservingOptionNew,我在下面的示例中使用它。

首先,「姓名」應該是ClassB中的公共財產。其次,您可能不需要將觀察者添加到ClassA中的viewWillAppear中的「b」中,因爲每次出現ClassA視圖時都不需要添加該觀察者。當您創建ClassB視圖時,您只需添加一次觀察者。一旦添加了觀察者,observeValueForKeyPath:ofObject:change:context:方法將在ClassA中執行,因此您可以從那裏更新到ClassA UI。每當ClassA即將出現時,您都不需要做任何事情。

在A類中,您應該在將ClassB推送到控制器堆棧之前創建ClassB,推測可能是在用戶執行某些操作的事件處理程序中。在創建ClassB之後,立即將ClassA中的觀察者添加到正確的NSKeyValueObservingOption值中。

如果你只是想通知每當ClassB的公共財產 「名稱」 變了,那就試試這個:

ClassB的

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 
+0

這可能是問題。您需要使用options參數來指示您想要的通知。通過傳入0,您不會要求通知任何事情。 – benzado 2010-11-10 22:38:42

+0

nekno,感謝您的幫助! – fmcauley 2010-11-11 02:08:30

+6

如果這有助於任何人,我有一個問題,我的observeValueForKeyPath消息沒有發射,即使我寫出來幾乎與nekno完全一樣。你*有*改變屬性使用self.name = newvalue,* NOT *只是name = newvalue。 – Mirkules 2011-03-12 00:35:36