AddObserver forkeypath ::没有响应

时间:2015-04-11 02:04:18

标签: ios objective-c

我有以下代码,我正在尝试观察变量,并在更改时重新生成文本。但到目前为止没有任何反应:/

-(void)viewdidload{    
    float Index = 1;//declared in header locally
    [self addObserver:self forKeyPath:@"Index" options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld context:nil];

    [self generateAdviceText];
 }   



-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context{
NSLog(@"inside");
if([keyPath isEqualToString:@"Index"]){
    NSLog(@"INDEX CHANGED");
    [self generateAdviceText];
}
}

-(void)generateAdviceText{
AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
NSString *name = ((User *)appDelegate.users[self.currentUserIndex]).name;
NSString *clothWear = @"HAT";

NSMutableAttributedString *adviceString = [[NSMutableAttributedString alloc]initWithString:@"\"..."];
[adviceString appendAttributedString:[self boldString:name]];
[adviceString appendAttributedString:[self normalString:@", remember be extra aware of the cats today. The index is "]];
[adviceString appendAttributedString:[self boldString:[@(Index) stringValue]]];
[adviceString appendAttributedString:[self normalString:@", sth "]];
[adviceString appendAttributedString:[self boldString:clothWear]];
[adviceString appendAttributedString:[self normalString:@" sth "]];
[adviceString appendAttributedString:[self boldString:sth]];
[adviceString appendAttributedString:[self normalString:@"...\""]];

self.adviceLabel.attributedText = adviceString;

}

有人可以发现我的错误吗?感谢

2 个答案:

答案 0 :(得分:2)

Key-Value Observing不会为实例变量(或任何其他类型的变量)的简单赋值生成更改通知。

在大多数情况下,您需要调用属性的setter来为该对象和该属性生成更改通知。

在较低级别,如果调用NSKeyValueObserving informal protocol中的-willChange...-didChange...方法,KVO仅会生成更改通知。在特定情况下调用这些方法:

  • 如果调用了由键命名的属性的正确命名的setter或集合变异访问器(假设+automaticallyNotifiesObserversForKey:为该键返回true)。这是最好的方式。

  • 如果NSKeyValueCoding informal protocol中的某个-set...方法被调用(例如-setValue:forKey:)(再次假设+automaticallyNotifiesObserversForKey:为该键返回true)。

  • 如果-mutable...ValueForKey:的{​​{1}}方法之一返回的集合代理被发送变异方法(再次,取决于NSKeyValueCoding)。

  • 如果某些代码(通常在定义属性的类中)手动调用+automaticallyNotifiesObserversForKey:-willChange...方法。

正如Joe Shang指出的那样,一个物体观察自身是值得怀疑的。如果某个对象想知道其属性的某个属性何时被更改,则应将相关代码放入其setter中。当然,它必须使用该setter专门修改其属性,而不是直接设置实例变量(就像KVO一样)。

在您发布的代码中,您也没有获得预期的KVO更改通知。您的代码将无限递归,直到它溢出堆栈时崩溃。您尝试进行此操作以便更改索引调用-didChange...并且-generateAdviceText更改索引。

答案 1 :(得分:1)

Index类型是什么?静态变量或属性? addObserver:forKeyPath:options:contexts:中的keyPath必须是某个对象的属性(兼容KVC),您可以阅读NSHipster's acticleobjc.io #7以获得更多。

另一方面,如果Index是属性,则不需要在此处使用KVO。您可以覆盖Index的setter方法,并在Index更新时执行某些操作。

- (void)setIndex:(int)index
{
    _index = index;
    // add you generateAdviceText method here
}