- (void)setFirstName:(NSString*)firstNameValue {
[self willChangeValueForKey:@"firstName"];
[firstName release];
firstName = firstNameValue;
[firstName retain];
[self didChangeValueForKey:@"firstName"];
}
是吗?所以willChange ... foobar didChange ... block导致KVO通知开火?
答案 0 :(得分:12)
不,您的实施不是100%正确。想想如果firstName当前设置为NSString-instance并且使用非常相同实例调用setter会发生什么。首先,你将释放实例,而不是你将设置实例变量,在这种情况下,它不会改变任何东西,而是你尝试保留实例,但到那时它很可能已被解除分配。
应该是:
- (void)setFirstName:(NSString*)firstNameValue {
[self willChangeValueForKey:@"firstName"];
[firstNameValue retain];
[firstName release];
firstName = firstNameValue;
[self didChangeValueForKey:@"firstName"];
}
或:
- (void)setFirstName:(NSString*)firstNameValue {
if (firstNameValue != firstName) {
[self willChangeValueForKey:@"firstName"];
[firstName release];
firstName = firstNameValue;
[firstName retain];
[self didChangeValueForKey:@"firstName"];
}
}
后一版本的另一个优点是,如果值没有真正改变,则不发送oberserver通知。
答案 1 :(得分:0)
是 - 调用didChangeValueForKey:
会通知所有观察者该值已更改。