【问题标题】:Send Notification When a Property is Changed Using KVO使用 KVO 更改属性时发送通知
【发布时间】:2013-01-30 01:49:43
【问题描述】:

我的班级中有一个名为 myName 的属性,例如:

@property (nonatomic, strong) NSString *myName;

myName 属性值发生更改时,我需要发送通知。

现在我正在做类似的事情:

- (void)setMyName:(NSString *)name
{
  _myName = name;
  [[NSNotificationCenter defaultCenter] postNotificationName:CHANGE_NOTIFICATION object:nil];
}

我知道在 iOS 中有类似 Key-Value Observing 的东西。但是我不知道如何实现,我阅读了整个文档,但无法很好地理解。

请帮助我了解如何在不使用自定义设置器的情况下实现相同的功能。

【问题讨论】:

    标签: ios objective-c properties key-value-observing


    【解决方案1】:

    试试这个:

    MyClass *var = [MyClass new];
    [var addObserver:self forKeyPath:@"myName" options:NSKeyValueChangeOldKey context:nil];
    

    并实施

    - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
    {
    
    }
    

    这个方法会在 myName 属性改变时随时调用

    【讨论】:

    • 嗨,我想知道 KVO 解决方案是否比其他实现解决方案更好。谁能解释一下?
    • @NiCTesla:这正是我的想法。只有在没有其他机制可以完成这项工作时才应使用 AFAIR KVO(此处为 NSOperation 示例)。我还认为通知会产生更易于理解、更不容易出错的代码。
    【解决方案2】:

    在- (void)setMyName:(NSString *)name 中改为这样做

    [self willChangeValueForKey:@"myName"];
    _myName = name;
    [self didChangeValueForKey:@"myName"];
    
    //this generates the KVO's
    

    在你想听的地方(viewController),在 viewDidLoad 中添加这一行:

    [w addObserver:self forKeyPath:@"myName" options:NSKeyValueObservingOptionNew context:nil];

    //通过这样做,你注册了viewController来监听KVO。

    也实现这个方法:

    - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
        if ([[change objectForKey:NSKeyValueChangeNewKey] isEqual:[NSNull null]]) {
            return;
        } else {
            //read the change dictionary, and have fun :)
        }
    }
    

    //只要属性值发生变化,就会调用这个方法。

    【讨论】:

    • 这个答案比公认的答案好很多,没有说明如何实现KVO,只说明如何监听已经实现的KVO通知
    【解决方案3】:

    要在没有客户设置器的情况下执行此操作,只需合成属性设置器即可。这将创建对 willChangeValueForKey / didChangeValueForKey 的所有支持调用。

    @synthesize myName;

    然后用点语法设置属性值:

    self.myName = @"Inigo Montoya"

    然后观察者会自动收到KVO通知。

    (您需要在释放被观察对象之前移除观察者。)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-06-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-06
      相关资源
      最近更新 更多