Question

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"];
Was it helpful?

Solution

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.

OTHER TIPS

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"];

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top