Реализовать собственный сеттер или использовать КВО? - PullRequest
12 голосов
/ 05 мая 2011

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

- (void)setProp:(NSString *)theProp
{
  if (prop != theProp){
    [prop release];
    prop = [theProp copy];
    [self myLogic];
  }
}

или:

- (void)observeValueForKeyPath:(NSString *)keyPath
                      ofObject:(id)object
                        change:(NSDictionary *)change
                       context:(void *)context
{
  if ([keyPath isEqualToString:@"prop"]){
    [self myLogic];
  }  
}

Какой путь лучшеи ПОЧЕМУ?

РЕДАКТИРОВАТЬ: я префект второго способа, потому что я не знаю, что компилятор будет генерировать директиву @synthesize для меня, я решил верить, что компилятор более умнее, чем моя реализация сеттеров, которые я долженследовательно, я не буду что-то ломать.

Ответы [ 3 ]

5 голосов
/ 05 мая 2011

Первый фрагмент - это путь, если вас интересуют изменения в том же объекте.Вам нужно использовать второе, только если вас интересуют изменения в других объектах, и использовать его для наблюдения self - это излишество.

3 голосов
/ 05 мая 2011

Сложный вызов, ИМХО оба варианта - отстой.

Первый вынуждает вас написать свой собственный установщик, который содержит много стандартного кода. (Не говоря уже о том, что вы должны помнить, что вы также должны запускать уведомления KVO с willChangeValueForKey: и didChangeValueForKey:, если хотите, чтобы KVO для рассматриваемого свойства работало.)

Второй варианттакже довольно тяжелый, и вашей реализации недостаточно.Что если в вашем суперклассе также есть немного КВО?Вам нужно было бы позвонить super где-нибудь в обработчике.Если нет, вы уверены, что ваш суперкласс не изменится?(Подробнее о KVO в связанном вопросе .)

Иногда вы можете обойти проблему, используя другие методы, такие как привязки (если вы на Mac) или обычные уведомления (вы можете опубликоватьуведомление о том, что модель изменилась, и все заинтересованные стороны должны обновить ее.)

Если у вас много подобных перерасчетов и вы не можете найти лучшего пути, я бы попытался написать суперкласс с лучшей поддержкой наблюдений, с интерфейсомкак это:

[self addTriggerForKeyPath:@"foo" action:^{
    NSLog(@"Foo changed.");
}];

Это займет больше работы, но будет держать ваши классы в чистоте, и вы сможете решить все проблемы, связанные с КВО, в одном месте.Если пересчитанных свойств недостаточно для этого, я обычно выбираю первое решение (пользовательский установщик).

0 голосов
/ 18 июля 2013

В вашем случае лучший вариант - добавить логику в сеттер.Реализация вашего сеттера верна, если ваше объявление свойства выглядит как

@ property (nonatomic, copy) YCYourClass * prop;

KVO обычно используется при проверке изменений свойств внешних объектов.

NSNotifications лучше подходят для информирования о событиях.

...