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

don*_*ile 3 iphone key-value-observing

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

是对的吗?所以willChange ... foobar doChange ...阻止导致KVO通知开火?

ton*_*lon 12

不,您的实施不是100%正确.认为,如果中的firstName当前设置为一个NSString的实例和调用setter时与非常会发生什么相同的实例.首先,你将释放实例,而不是你将设置实例变量,在这种情况下,它不会改变任何东西,而是你尝试保留实例,但到那时它很可能已被解除分配.

它应该是:

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

要么:

- (void)setFirstName:(NSString*)firstNameValue {
    if (firstNameValue != firstName) {
        [self willChangeValueForKey:@"firstName"];
        [firstName release];
        firstName = firstNameValue;
        [firstName retain];
        [self didChangeValueForKey:@"firstName"];
    }
}
Run Code Online (Sandbox Code Playgroud)

后一版本的另一个优点是,如果值没有真正改变,则不发送oberserver通知.