我在我的Objective-C AppDelegate中有一个名为stepsCompleted
的公共变量,因此我使用[AppDelegate instance]->stepsCompleted
。
我希望我的表观视图控制器告诉我该变量的值何时更改,因此我在initWithCoder:
方法中进行以下操作,我知道正在称为:
[self addObserver:self forKeyPath:@"[AppDelegate instance]->stepsCompleted" options:0 context:NULL];
但是,尽管我在AppDelegate中不断更改stepsCompleted
,但我的方法:
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
}
从未被调用。
我到底在做什么?
您的代码有不同的问题。首先,键值观察是观察对象的属性的机制。它与实例不起作用变量。因此,您应该将" Stepspleted"声明为应用程序委托的属性,而不是实例变量:
@property (nonatomic) int stepsCompleted;
并通过属性登录方法设置其值,例如
[AppDelegate instance].stepsCompleted = newValue;
接下来,"[AppDelegate instance]->c"
不是关键路径,您必须指定至少一个观察选项,例如NSKeyValueObservingOptionNew
。
要观察[AppDelegate instance]
的"步骤结合"属性,应该是
[[AppDelegate instance] addObserver:self
forKeyPath:@"stepsCompleted"
options:NSKeyValueObservingOptionNew
context:NULL];
尽管这是最快,最简单的方法,但您实际上不需要声明@property
即可使用KVO,但您只需要确保在正确调用Willchange和DIDCHANGE之前正确地供该属性,以及一种访问它的方法。
例如,在大多数手动情况下,您可以这样实现stepsCompleted
:
@implementation SomeClass {
int _stepsCompleted;
}
- (void)setStepsCompleted:(int)stepsCompleted;
{
[self willChangeValueForKey:@“stepsCompleted”];
_stepsCompleted = stepsCompleted;
[self didChangeValueForKey:@“stepsCompleted”];
}
- (int)stepsCompleted;
{
return _stepsCompleted;
}
@end
然后,如果您在" someobject"上观察到" sptepplet"的键,则在更改时会被调用,假设您只能使用其设置器进行更改,例如通过:
[self stepsCompleted:10];
但是,由于Apple引入了属性,因此可以将上述缩短到完全等价:
self.stepsCompleted = 10;
,但这对于二传手和Getter来说仍然是很多代码,您不必写所有这些代码,因为苹果在过去几年中做了一些很酷的事情。一个是@property符号,基本上是为您编写上面的设置/获取代码(其中一些额外的好东西扔进去)。因此,现在您可以放入.h文件:
@property int stepsCompleted;
将为您编写这两种方法。只要您确保仅使用点通知或直接致电setter,kvo就可以工作。