когда использовать “willChangeValueForKey” и “didChangeValueForKey”?

Я видел эти строки в демонстрационном проекте, но я не мог понять, почему он сделал это.

[self willChangeValueForKey:@"names"];
[self didChangeValueForKey:@"names"];

Это сразу назвало didChangeValueForKey после willChangeeValueForKey. Это имеет какой-либо смысл?

Кроме того, когда должно быть правильное время для вызова этого двумя методами?Большое спасибо!!:)

29
задан Frost 10 June 2010 в 20:28
поделиться

3 ответа

Фактически, это антипаттерн. Вы не должны вызывать -willChangeValueForKey: , за которым следует -didChangeValueForKey: без какого-либо фактического изменения свойства. В некоторых случаях это может замаскировать проблемы KVO в другом месте вашего кода и вынудить наблюдателей обновить свое состояние, связанное с рассматриваемым свойством. Однако в конечном итоге вы (или автор приведенного вами примера) должны исправить остальную часть кода, чтобы в этом анти-шаблоне не было необходимости.

Правильное использование -will | didChangeValueForKey: - это когда вы изменяете свойство без использования KVC-совместимых средств доступа / установки, так что механизм KVO не заметит изменения. В качестве надуманного примера рассмотрите возможность изменения переменной экземпляра поддержки для атрибута напрямую:

@interface Foo
{
   int bar;
}
@end

@implementation Foo
- (void)someMethod
{
  bar = 10;
}
@end

Наблюдатели KVO, которые зарегистрировались для уведомления об изменениях в свойстве bar , не будут получать уведомление об изменении в bar в -someMethod . Чтобы заставить механизм KVO работать, вы можете изменить -someMethod :

- (void)someMethod
{
  [self willChangeValueForKey:@"bar"];
  bar = 10;
  [self didChangeValueForKey:@"bar"];
}

Конечно, было бы лучше использовать объявление @property и использовать KVC-совместимые средства доступа / установки (либо вручную, либо @synthesized ), но это надуманный пример.

49
ответ дан 28 November 2019 в 01:22
поделиться

Это связано с ручным управлением наблюдением за значением ключа. Обычно об этом заботится система, но эти параметры позволяют вам контролировать ситуацию. Посмотрите эту документацию, чтобы понять, когда и как их использовать здесь.

1
ответ дан 28 November 2019 в 01:22
поделиться
  • Если вы хотите что-то сделать непосредственно перед изменением значения, используйте willChangeValueForKey.
  • Если вы хотите сделать что-то сразу после изменения значения, используйте didChangeValueForKey.

Изменить: игнорировать меня, читал слишком быстро - Барри прав: -)

0
ответ дан 28 November 2019 в 01:22
поделиться