rus*_*ord 27 cocoa cocoa-touch objective-c key-value-observing
在以下方法中使用context参数有什么用于注册键值通知.文档只是将其表示为任意数据集.
addObserver:self forKeyPath:@"selectedIndex" options:NSKeyValueObservingOptionNew context:nil
Run Code Online (Sandbox Code Playgroud)
有人可以说清楚它背后的目的是什么......
rob*_*off 79
我希望这个解释不是太抽象,不能理解.
假设您创建了一个类MyViewController
,它是一个类的子类UIViewController
.你没有源代码UIViewController
.
现在你决定MyViewController
使用KVO来观察center
属性的变化self.view
.所以你适当地添加自己作为观察者:
- (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];
}
Run Code Online (Sandbox Code Playgroud)
这里的问题是,你不知道是否UIViewController
也将自己注册为观察员self.view
的center
.如果是,那么您可能会遇到两个问题:
UIViewController
KVO注册.您需要一种方法来将自己注册为UIViewController
与KVO注册区别开来的观察者.这就是在context
争论进来.你需要传递一个值context
,你有绝对的把握UIViewController
是不会使用的context
参数.当您取消注册时,context
再次使用相同的内容,这样您只能删除注册,而不是UIViewController
注册.在您的observeValueForKeyPath:ofObject:change:context:
方法中,您需要检查context
消息是为您还是为您的超类.
确保使用context
其他任何其他用途的一种方法是创建一个static
变量MyViewController.m
.注册和取消注册时使用它,如下所示:
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];
}
Run Code Online (Sandbox Code Playgroud)
然后在您的observeValueForKeyPath:...
方法中,检查它:
- (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];
}
}
Run Code Online (Sandbox Code Playgroud)
现在你保证不会干扰你的超类的KVO,如果有的话.如果有人制作的子类MyViewController
也使用KVO,它不会干扰你的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];
}
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
4506 次 |
最近记录: |