如果我想编写自己的符合 KVO 的 setter 方法,它会看起来像这样吗?

发布于 2024-09-04 17:03:43 字数 315 浏览 4 评论 0原文

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

是这样吗?那么 willChange... foobar didChange... 块会导致 KVO 通知触发吗?

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

Is that right? So the willChange... foobar didChange... block causes an KVO notification to fire?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

烛影斜 2024-09-11 17:03:43

不,您的实施并非 100% 正确。想象一下,如果当前将firstName设置为NSString实例并且使用该相同实例调用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-notifications。

No, your implementation is not 100% correct. Think what happens if the firstName is currently set to a NSString-instance and the setter is called with that very same instance. First you will release the instance, than you will set the instance variable, which in this case dosen't change anything and than you try the retain the instance, but by that time it could very well been dealloced already.

It should be:

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

or:

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

The latter version has the additional advantage of not sending oberserver-notifications if the value is not really changed.

如果没有 2024-09-11 17:03:43

- 调用didChangeValueForKey: 将通知所有观察者该值已更改。

Yes - calling didChangeValueForKey: will notify all the observers that the value has changed.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文