@synthesized属性和KVC

时间:2011-12-04 22:16:30

标签: objective-c kvc

使用@synthesize生成的setter是否应该对KVC进行编译?我发现声明生成的getter和setter符合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 个答案:

答案 0 :(得分:8)

我认为你的方法错了。符合KVC并不意味着访问者会调用-setValue:forKey:符合KVC意味着调用-setValue:forKey:会调用访问者。

扩展一点: KVC兼容仅表示'遵循命名约定'。为什么这很重要?我可以随心所欲地调用我的访问器方法。对于房产'Foo':

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

这很好。但像Bindings这样的机制会尝试通过调用

来设置Foo
[ob setValue:newVal forKey:@"foo"];

-setValue:forKey:将尝试做正确的事情并使用访问器方法(如果我们编写了一个setter方法,那是因为我们希望它被使用,对吧?)。但除非我们将我们的setter方法命名为标准-setFoo:,否则无法找到它。

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

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

答案 1 :(得分:2)

您不需要为KVO实现setValueForKey :.它是在框架内为您实现的。通过使您的属性符合KVO(使用@property和@synthesize完成),一切都可以“神奇地”工作

-----更新

此外,您的测试代码不会测试KVO。要测试它,请执行以下操作:

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

答案 2 :(得分:2)

实际上反过来了。 这些是setValue:forKeygetValueforKey,它们会查找符合KVC标准的属性,而不是通过它们合成的属性。

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