@synthesized 属性和 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"];
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"];
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我认为你搞错了。符合 KVC 并不意味着访问器会调用
-setValue:forKey:
符合 KVC 意味着调用-setValue:forKey:
将调用访问器。扩展一下:符合 KVC 仅意味着“遵循命名约定”。为什么这很重要?我可以将我的访问器方法称为任何我喜欢的名称。对于属性“Foo”:
这很好。但是像 Bindings 这样的机制会尝试通过调用
-setValue:forKey:
来设置 Foo,它将尝试做正确的事情并使用访问器方法(如果我们编写了一个 setter 方法,那是因为我们希望它会被使用,对吧?)。但除非我们将 setter 方法命名为标准-setFoo:
,否则就无法找到它。因此
-weakSetFoo:
是一个 setter 方法,但属性 Foo 不符合 KVC。如果我将 setter 名称更改为
-setFoo:
属性 Foo 现在符合 KVC 标准。默认情况下,合成的访问器方法将被正确命名。
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':
This is fine. But a mechanism like Bindings will try to set Foo by calling
-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.
您不需要为 KVO 实现 setValueForKey: 。它是在框架内为您实现的。通过使您的属性符合 KVO(您已使用 @property 和 @synthesize 完成),一切都会“神奇”地工作
----- update
另外,您的测试代码不会测试 KVO。要测试它,请执行以下操作:
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:
事实上恰恰相反。
它们是
setValue:forKey
和getValueforKey
,它们查找符合 KVC 的属性,而不是通过它们合成的属性。当您编写
@synthesize property
时,编译器实际上只是填充- (type) property
和- (void) setProperty: (type)value
类型读取/设置相应实例变量的方法。It is actually the other way round.
These are
setValue:forKey
andgetValueforKey
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.