Reputation: 3784
Should setter generated with @synthesize be KVC compilant or not? I found statement that getters and setters generated are KVC-compliant, shouldn't it call one of this methods?
@interface testing : NSObject
@property (nonatomic, retain) NSString *phone;
@end
implementation:
@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
and test it with:
testing *t = [[testing alloc] init];
[t setPhone:@"55555555"];
Upvotes: 1
Views: 2047
Reputation: 9198
I think you've got it the wrong way round.. KVC compliant doesn't mean that an accessor will call -setValue:forKey:
Being KVC compliant means that calling -setValue:forKey:
will call the accessor.
Expanding a bit: KVC compliant only means 'follows naming conventions'. Why is this important? I can call my accessor methods anything i like. For a property 'Foo':
- (void)weakSetFoo:(id)f;
- (id)autoreleasedFoo;
This is fine. But a mechanism like Bindings will try to set Foo by calling
[ob setValue:newVal forKey:@"foo"];
-setValue:forKey:
will try to do the right thing and use the accessor method (if we wrote a setter method, it's because we want it to be used, right?). But unless we named our setter method the standard -setFoo:
there's no way it will be found.
So -weakSetFoo:
is a setter method, but the property Foo isn't KVC compliant.
If i change the setter name to -setFoo:
the property Foo is now KVC compliant.
Synthesized accessor methods will by default be named correctly.
Upvotes: 8
Reputation: 11552
It is actually the other way round.
These are setValue:forKey
and getValueforKey
which look up the KVC-compliant properties, not properties synthesized through them.
When you write @synthesize property
the compiler actually just stuffs - (type) property
and - (void) setProperty: (type)value
kind of methods which read/set corresponding instance variable.
Upvotes: 2
Reputation: 15588
You don't need to implement setValueForKey: for KVO. It is implemented for you within the framework. By making your properties KVO compliant (which you have done using @property and @synthesize), everything just works 'magically'
----- update
Also, your testing code would not test KVO. To test it, do something like:
testing *t = [[testing alloc] init];
[t setValue:@"55555555" forKey:@"phone"];
Upvotes: 2