在用於註冊關鍵值通知的以下方法中,上下文參數有什麼用處。文件只是將其表示爲任意數據。關鍵值觀察中的上下文參數的重要性
addObserver:self forKeyPath:@"selectedIndex" options:NSKeyValueObservingOptionNew context:nil
有人可以提供一些線索什麼是其背後的目的...
感謝
在用於註冊關鍵值通知的以下方法中,上下文參數有什麼用處。文件只是將其表示爲任意數據。關鍵值觀察中的上下文參數的重要性
addObserver:self forKeyPath:@"selectedIndex" options:NSKeyValueObservingOptionNew context:nil
有人可以提供一些線索什麼是其背後的目的...
感謝
我希望這個解釋是不是太過抽象理解。
假設您創建了一個類MyViewController
,它是UIViewController
的一個子類。您沒有源代碼UIViewController
。
現在您決定讓MyViewController
使用KVO觀察對self.view
的center
財產的更改。所以,你正式加入自己作爲觀察員:
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[self.view addObserver:self forKeyPath:@"center" options:0 context:NULL];
}
- (void)viewDidDisappear:(BOOL)animated {
[self.view removeObserver:self forKeyPath:@"center"];
[super viewDidDisappear:animated];
}
這裏的問題是,你不知道,如果UIViewController
也將自己註冊爲self.view
的center
的觀察員。如果是這樣,那麼你可能有兩個問題:
UIViewController
的KVO註冊。您需要一種方法將自己註冊爲與UIViewController
的KVO註冊不同的觀察者。這就是context
的論點。你需要傳遞一個值爲context
,你絕對相信UIViewController
是而不是使用作爲context
參數。當您取消註冊時,您再次使用相同的context
,以便您只刪除註冊,而不是UIViewController
的註冊。在observeValueForKeyPath:ofObject:change:context:
方法中,您需要檢查context
以查看該消息是針對您還是針對您的超類。
確保使用context
的其中一種方法是,在MyViewController.m
中創建一個static
變量。當你註冊和註銷,像這樣使用它:在您的observeValueForKeyPath:...
方法
static int kCenterContext;
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[self.view addObserver:self forKeyPath:@"center" options:0 context:&kCenterContext];
}
- (void)viewDidDisappear:(BOOL)animated {
[self.view removeObserver:self forKeyPath:@"center" context:&kCenterContext];
[super viewDidDisappear:animated];
}
然後,檢查它像這樣:
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object
change:(NSDictionary *)change context:(void *)context
{
if (context == &kCenterContext) {
// This message is for me. Handle it.
[self viewCenterDidChange];
// Do not pass it on to super!
} else {
// This message is not for me; pass it on to super.
[super observeValueForKeyPath:keyPath ofObject:object
change:change context:context];
}
}
現在你不能保證你的超類的志願干擾,如果它做任何。如果有人使用也使用KVO的MyViewController
的子類,它不會干擾您的KVO。
還要注意,您可以爲您觀察的每個關鍵路徑使用不同的上下文。然後,當系統通知您有更改時,您可以檢查上下文而不是檢查關鍵路徑。測試指針相等性比檢查字符串相等性要快一些。例如:
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object
change:(NSDictionary *)change context:(void *)context
{
if (context == &kCenterContext) {
[self viewCenterDidChange];
// Do not pass it on to super!
} else if (context == &kBackgroundColorContext) {
[self viewBackgroundDidChange];
// Do not pass it on to super!
} else if (context == &kAlphaContext) {
[self viewAlphaDidChange];
// Do not pass it on to super!
} else {
// This message is not for me; pass it on to super.
[super observeValueForKeyPath:keyPath ofObject:object
change:change context:context];
}
}
[參數從observeValueForKeyPath:ofObject變化:背景:]的
感謝很多關於你的詳細解釋真的很感激。一段時間以來,我一直困惑着爲什麼這個參數很重要,並且你的回答能夠澄清它。 :) – rustylepord 2012-08-12 08:19:24
你好我可以使用上下文來設置一些對象,稍後當通知來檢索它時o根據存儲在上下文中的值執行一些特定的任務。 – Sandeep 2012-11-26 15:06:34
+1精彩的解釋。 (一個單獨的警告:'UIView'的屬性不符合KVO,不能觀察'view.center'。) – 2013-10-08 15:48:59
可能重複(http://stackoverflow.com/questions/1625575/parameters-from-observevalueforkeypathofobjectchangecontext) – 2012-08-11 19:06:23