有没有办法观察派生属性的变化?例如,我想知道何时添加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问题。我该怎么办?提前谢谢!
答案 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中执行的任何操作都将无效。