观察派生属性的变化:CALayer KVO示例

时间:2009-04-02 15:09:58

标签: objective-c cocoa

有没有办法观察派生属性的变化?例如,我想知道何时添加CALayer作为子图层,以便我可以相对于其(新)父级调整其几何。

所以,我有一个子类CALayer,比如CustomLayer,我想我可以在init中为该属性注册一个观察者:

[self addObserver:self forKeyPath:@"superlayer" options:0 context:nil]

并实施observeValueForKeyPath:ofObject:change:context。什么都没发生,因为,大概是,superlayer是派生属性(attr字典存储父母的不透明ID)。同样,我不能继承setSuperlayer:,因为它永远不会被调用。实际上,据我所知,当父进行[self addSublayer:aCustomLayer]时,子层上没有设置实例方法或公共属性。

然后我想,好吧,我会像这样继承addSublayer:

- (void)addSublayer:(CALayer *)aLayer {
    [aLayer willChangeValueForKey:@"superlayer"];
    [super addSublayer:aLayer];
    [aLayer didChangeValueForKey:@"superlayer"];
}

但仍然没有! (也许这是一个线索,当我创建一个简单的独立测试类并使用will[did]ChangeValueForKey:然后它可以工作。)这可能是一个更普遍的Cocoa KVO问题。我该怎么办?提前谢谢!

2 个答案:

答案 0 :(得分:9)

好吧,superlayer被定义为readonly属性,这意味着没有setSuperlayer:方法。 (如果有,它将是私有的,你可能不应该使用它。)如果我不得不猜测,那就是superlayer属性不符合KVO。而且,除此之外,我通常不认为课堂观察自己是个好主意。

也许有另一种方法可以做到这一点。将图层添加到超级图层时,会发生onOrderIn操作。现在,actionForKey:是一种实例方法,它为图层提供了为某些属性自定义默认动画的机会。您可以覆盖actionForKey:以检测onOrderIn操作何时发生,执行您的操作,然后调用super的实施。

我认为这也是一个非常混乱的黑客。但它应该比自己使用自定义图层以及弄乱KVO消息更加“自足”。

答案 1 :(得分:0)

[self addObserver:self forKeyPath:@"superlayer" options:0 context:nil]

不要通过KVO观察自己。改为改变你的访问者。

  

同样,我不能将setSuperlayer子类化:因为它永远不会被调用。

我认为你试过这个并添加了NSLog并发现它没有被调用?

  

然后我想,好吧,我会像这样继承addSublayer:

- (void)addSublayer:(CALayer *)aLayer {
    [aLayer willChangeValueForKey:@"superlayer"];
    [super addSublayer:aLayer];
    [aLayer didChangeValueForKey:@"superlayer"];
}

父图层也是CustomLayer,对吧?如果父图层是普通CALayer,那么您在CustomLayer中执行的任何操作都将无效。