@ синтезированные свойства и KVC - PullRequest
1 голос
/ 05 декабря 2011

Должен ли сеттер, сгенерированный с помощью @synthesize, быть KVC-совместимым или нет?Я нашел утверждение, что сгенерированные геттеры и сеттеры являются KVC-совместимыми, разве он не должен вызывать один из этих методов?

@interface testing : NSObject
@property (nonatomic, retain) NSString *phone;
@end

реализация:

@implementation testing
@synthesize phone;

- (id)init {
    self = [super init];
    return self;
}

// none of these is called with dot syntax, or setter setPhone
- (void)setValue:(id)value forKey:(NSString *)key
{
    NSLog(@"%@",key);
    [super setValue:value forKey:key];
}

-(void)setValue:(id)value forKeyPath:(NSString *)keyPath
{
    NSLog(@"%@",keyPath);
    [super setValue:value forKeyPath:keyPath];
}

@end

и протестировать его с помощью:

testing *t = [[testing alloc] init];
[t setPhone:@"55555555"];

Ответы [ 3 ]

8 голосов
/ 05 декабря 2011

Я думаю, вы ошиблись. Совместимость с KVC не означает, что метод доступа будет вызывать -setValue:forKey: Совместимость с KVC означает, что вызов -setValue:forKey: вызовет метод доступа.

Расширение немного: KVC-совместимый означает только то, что следует соглашениям по присвоению имен .Почему это важно?Я могу вызывать методы доступа как угодно.Для свойства 'Foo':

- (void)weakSetFoo:(id)f;
- (id)autoreleasedFoo;

Это хорошо.Но такой механизм, как Bindings, попытается установить Foo путем вызова

[ob setValue:newVal forKey:@"foo"];

-setValue:forKey:, который попытается сделать правильную вещь и использовать метод доступа (если мы написали метод установки, это потому, что мы хотим, чтобы ониспользоваться, верно?).Но если мы не назовем наш метод установки стандартным -setFoo:, мы не сможем найти его.

Таким образом, -weakSetFoo: является методом установки, но свойство Foo не соответствует KVC.Если я изменю имя установщика на -setFoo:, свойство Foo теперь совместимо с KVC.

Методы синтезированного метода доступа по умолчанию будут иметь правильные имена.

2 голосов
/ 05 декабря 2011

На самом деле все наоборот. Это setValue:forKey и getValueforKey, которые ищут свойства, совместимые с KVC, а не свойства, синтезированные через них.

Когда вы пишете @synthesize property, компилятор на самом деле просто набирает - (type) property и - (void) setProperty: (type)value методы, которые читают / устанавливают соответствующую переменную экземпляра.

2 голосов
/ 05 декабря 2011

Вам не нужно реализовывать setValueForKey: для KVO. Это реализовано для вас в рамках. Делая ваши свойства совместимыми с KVO (что вы сделали с помощью @property и @synthesize), все просто работает «волшебно»

----- обновление

Кроме того, ваш код тестирования не будет проверять KVO. Чтобы проверить это, сделайте что-то вроде:

testing *t = [[testing alloc] init];
[t setValue:@"55555555" forKey:@"phone"];
...