2011-12-04 23 views
1

使用@synthesize生成的setter是KVC compilant还是不是?我发现getter和setter生成的声明符合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"]; 

回答

8

我认为你错了。符合KVC并不意味着访问者会打电话-setValue:forKey:符合KVC意味着调用-setValue:forKey:将调用访问者。

有点扩大:KVC标准只意味着'如下命名约定'。为什么这很重要?我可以调用我喜欢的访问器方法。对于属性'Foo':

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

这很好。但是,像绑定的机制将尝试通过调用

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

-setValue:forKey:设置美孚将尝试做正确的事,并使用访问方法(如果我们写了一个setter方法,这是因为我们希望它被使用,正确的?)。但是,除非我们将制定者方法命名为标准-setFoo:,否则将无法找到它。

所以-weakSetFoo:是一个setter方法,但属性Foo不符合KVC。 如果我将设置者名称更改为-setFoo:,则Foo属性现在与KVC兼容。

默认情况下,合成存取器方法将被正确命名。

2

你并不需要实现setValueForKey:为志愿。它在框架内为您实施。通过使您的属性志愿兼容(您已使用@property和@synthesize完成),一切都只是工作“神奇”

-----更新

另外,你的测试代码不考志愿。要测试它,请执行如下操作:

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

我正在测试生成的setter是KVO compilant的语句,这就是为什么我使用setter,而不是setValue itselt。我知道调用setValue的工作,但调用生成的setter不会在“测试”上调用setValue。 – Marcin

2

实际上这是相反的方式。 这些是setValue:forKeygetValueforKey,它们查找符合KVC的属性,而不是通过它们合成的属性。

当你编写@synthesize property时,编译器实际上只是填充- (type) property- (void) setProperty: (type)value类型的读取/设置相应实例变量的方法。