1

使用@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"];
4

3 回答 3

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:,否则无法找到它。

setter 方法也是如此-weakSetFoo:,但属性 Foo 不符合 KVC。如果我将设置器名称更改-setFoo:为属性 Foo 现在符合 KVC。

默认情况下,合成的访问器方法将被正确命名。

于 2011-12-04T22:31:44.597 回答
2

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

- - - 更新

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

testing *t = [[testing alloc] init];
[t setValue:@"55555555" forKey:@"phone"];
于 2011-12-04T22:20:39.477 回答
2

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

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

于 2011-12-04T22:25:16.213 回答