【问题标题】:If I wanted to write my own KVO-compliant setter method, would it look something like this?如果我想编写自己的符合 KVO 的 setter 方法,它看起来像这样吗?
【发布时间】:2010-06-08 10:59:35
【问题描述】:
- (void)setFirstName:(NSString*)firstNameValue {
    [self willChangeValueForKey:@"firstName"];
    [firstName release];
    firstName = firstNameValue;
    [firstName retain];
    [self didChangeValueForKey:@"firstName"];
}

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

【问题讨论】:

  • 为什么不直接使用合成属性?
  • 因为我想了解幕后发生的事情。
  • 这将是一个非常糟糕的泄漏@property (assign) setter - 也许包括您试图在问题中模仿的内容?

标签: iphone key-value-observing


【解决方案1】:

不,您的实现并非 100% 正确。想想如果 firstName 当前设置为 NSString-instance 并且使用该 same 实例调用 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 的额外优势。

【讨论】:

  • 除了第一种情况下的序列和第二种情况下的无操作检查之外,您的实现没有区别。你的反对票是不公平的。保留后分配与在无操作示例中分配然后保留的效果相同。最重要的是 setter 方法根据所需的行为保留、分配或复制。委托和原始 ivars 使用赋值。
  • 记住保留和复制返回id所以[firstName release]; firstName = [firstNameValue 保留];或 [firstName release]; firstName = [firstNameValue 副本];根据所需的行为可以解决问题。
  • @falconcreek:您没有阅读我的回答。当您想要保留 firstNameValue 时,可能已经被释放了。
  • +1,这是关于二传手的一个很好的观点,“没有区别..除了序列”完全没有抓住重点。请注意,这是一个非原子设置器(即@property (nonatomic,retain)),为原子情况添加适当的锁定。
  • “没有区别...”评论实际上是不正确的,我很抱歉。需要更加强调可能是同一个实例,如果在保留之前释放 如果发送消息的对象没有传入的对象的所有权,则会导致崩溃. 进一步阅读developer.apple.com/mac/library/documentation/Cocoa/Conceptual/…“内存管理编程指南”后,有人可能会争辩说不应该使用第一个版本。经过所有这些讨论......使用@synthesize!!!
【解决方案2】:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-23
    • 1970-01-01
    • 2021-03-21
    • 1970-01-01
    • 2021-06-14
    • 1970-01-01
    相关资源
    最近更新 更多