gpt4 book ai didi

objective-c - Key value observing中的context参数是做什么用的

转载 作者:太空狗 更新时间:2023-10-30 03:10:20 24 4
gpt4 key购买 nike

以下方法中的上下文参数有什么用,用于注册键值通知。文档只是将其表示为任意数据集。

addObserver:self forKeyPath:@"selectedIndex" options:NSKeyValueObservingOptionNew context:nil

有人可以阐明它背后的目的是什么......

最佳答案

我希望这个解释不会太抽象而难以理解。

假设您创建一个类 MyViewController ,它是 UIViewController 的子类.您没有 UIViewController 的源代码.

现在你决定制作MyViewController使用 KVO 观察 center 的变化self.view的属性(property).因此,您正式将自己添加为观察员:

- (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 .如果是这样,那么您可能会遇到两个问题:

  1. 当 View 的中心发生变化时,您可能会被调用两次。
  2. 当您删除自己的观察员身份时,您可能还会删除 UIViewController的 KVO 注册。

您需要一种方法将自己注册为观察者,以区别于 UIViewController的 KVO 注册。那就是 context 的地方参数进来了。您需要为 context 传递一个值你绝对确定UIViewController 用作context争论。注销时,您使用相同的 context再次这样你只删除你的注册,而不是UIViewController的注册。在你的 observeValueForKeyPath:ofObject:change:context:方法,你需要检查context看看这条消息是给你的,还是给你的父类(super class)的。

确保使用 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];
}

然后在你的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];
}
}

现在您可以保证不会干扰父类(super class)的 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];
}
}

关于objective-c - Key value observing中的context参数是做什么用的,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11916502/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com