如果我想编写自己的KVO兼容的setter方法,它会是这样的吗?

时间:2010-06-08 10:59:35

标签: iphone key-value-observing

- (void)setFirstName:(NSString*)firstNameValue {
    [self willChangeValueForKey:@"firstName"];
    [firstName release];
    firstName = firstNameValue;
    [firstName retain];
    [self didChangeValueForKey:@"firstName"];
}

是吗?所以willChange ... foobar didChange ... block导致KVO通知开火?

2 个答案:

答案 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:会通知所有观察者该值已更改。