Наблюдение за изменениями производных свойств: пример CALayer KVO - PullRequest
1 голос
/ 02 апреля 2009

Есть ли способ наблюдать изменения в производных свойствах? Например, я хочу знать, когда CALayer был добавлен в качестве подслоя, чтобы я мог настроить его геометрию относительно его (нового) родителя.

Итак, у меня есть подкласс CALayer, скажем CustomLayer, и я решил, что могу зарегистрировать наблюдателя для свойства в init:

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

и внедрить observeValueForKeyPath:ofObject:change:context. Ничего не происходит, потому что, по-видимому, суперслой является производным свойством (словарь attr хранит непрозрачный идентификатор для родителя). Точно так же я не могу подкласс setSuperlayer:, потому что он никогда не вызывается. На самом деле, насколько я могу судить, нет никаких вызванных методов экземпляра или открытых свойств на подуровне, когда родитель делает [self addSublayer:aCustomLayer].

Тогда я подумал, хорошо, я сделаю подкласс addSublayer следующим образом:

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

но все равно ничего! (Возможно, это подсказка, что когда я делаю простой автономный тестовый класс и использую will[did]ChangeValueForKey:, тогда он работает.) Возможно, это более общий вопрос Cocoa KVO. Что мне делать? Заранее спасибо!

Ответы [ 2 ]

9 голосов
/ 02 апреля 2009

Ну, superlayer определяется как свойство readonly, что означает отсутствие метода setSuperlayer:. (Если это так, он будет закрытым, и вам, вероятно, не следует его использовать.) Если бы мне пришлось делать предположение, то свойство superlayer просто не было бы совместимым с KVO. И, кроме того, я, как правило, не думаю, что классам следует наблюдать за собой.

Может быть, есть другой способ сделать это. Когда слой добавляется в суперслой, происходит действие onOrderIn. Теперь actionForKey: - это метод экземпляра, который дает слою возможность настраивать анимацию по умолчанию для определенных свойств. Вы можете переопределить actionForKey:, чтобы определить, когда происходит действие onOrderIn, сделать свое дело, а затем вызвать реализацию super.

Я тоже считаю это довольно грязным хаком. Но это должно быть немного более «автономным», чем необходимость использовать собственные слои для всего и возиться с сообщениями KVO.

0 голосов
/ 02 апреля 2009
[self addObserver:self forKeyPath:@"superlayer" options:0 context:nil]

Не наблюдай себя через КВО. Вместо этого поменяйте свои аксессоры.

Точно так же я не могу создать подкласс setSuperlayer: потому что он никогда не вызывается.

Я так понимаю, вы попробовали это, добавили NSLog и обнаружили, что он не вызывается?

Тогда я подумал, хорошо, я сделаю подкласс addSublayer следующим образом:

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

И родительский слой также является CustomLayer, верно? Если родительский слой является простым CALayer, все, что вы делаете в CustomLayer, не будет иметь никакого эффекта.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...