在iOS中观察链式KVO实体的良好模式?

时间:2014-01-23 01:18:09

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

我做了一些简单的KVO设置。现在我有点复杂了。我有一个可设置的单例对象。可通过

等代码访问
[Site singleton].value

我可以(并且有)观察singletonvalue属性的更改。但我还想看一个当前值的属性(如果它不是零)。它有一个valves属性,我想注意它的变化。

不知道更好,我想我可以做点像

  1. 观察{I}惯用的value属性
  2. 如果更改,请在当前值的valves属性上注册一个监视,如果它是非零的
  3. 另外,不知何故,不确定如何执行此操作,取消注册在valves上观看的所有value
  4. 这似乎很麻烦。

    我发现您可以执行更复杂的keyPath,但我找不到解释如何使用它们的文档。它们是否可以使这个问题更容易?如果没有,这是其他人找到一个很好的解决方案吗?

2 个答案:

答案 0 :(得分:3)

如果我对所涉及的代码有更多了解,我可以提供更好的答案,但这应该很容易。我将假设观察者是一个视图控制器,但这是设置它的最直接的方法。

- (void)viewWillAppear:(BOOL)animated
{
    // …
    [[Site singleton] addObserver:self forKeyPath:@"value" options:0 context:NULL];
    [[Site singleton] addObserver:self forKeyPath:@"value.valves" options:0 context:NULL];
}

- (void)viewWillDisappear:(BOOL)animated
{
    // …
    [[Site singleton] removeObserver:self forKeyPath:@"value"];
    [[Site singleton] removeObserver:self forKeyPath:@"value.valves"];
}

- (void)observeValueForKeyPath:(NSString *)keyPath
                      ofObject:(id)object
                        change:(NSDictionary *)change
                       context:(void *)context
{
    if ([keyPath isEqualToString:@"value"]) {
        // …
    } else if ([keyPath isEqualToString:@"value.valves"]) {
        // …
    }
}

请参阅Key-Value Coding Fundamentals

KVO的建议

  1. 观察您知道完整生命周期的内容。单身是一个很好的选择,只要它真正适用于应用程序的整个生命周期。一般来说,我坚持观察自己的物体。

  2. 当您需要观察时立即添加观察者,一旦不再需要观察就移除观察者。始终在-init*中添加观察者并在-dealloc中将其删除是一件麻烦事。

答案 1 :(得分:2)

是的,您可以在self.singleton中观察keyPath @“value.valves”:

- (void)addObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath options:(NSKeyValueObservingOptions)options context:(void *)context;

每当value更改或valves更改时,您都会收到通知。

但是,请注意,如果值未经正确发布willChange ... / didChange ...而发生更改,则会出现运行时错误。大多数'价值的通知将由setter机制为你发布,但如果你有一个weak引用它,它可以删除自己而不发布,这是非常烦人的,而且是一个非常愚蠢的事情。 / p>

另请注意,如果Valve是一个mutableArray你正在玩火,因为它会在没有得到通知的情况下发生变异。