@synthesized 属性和 KVC

发布于 2024-12-19 06:54:55 字数 766 浏览 1 评论 0原文

使用 @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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

节枝 2024-12-26 06:54:55

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

扩展一下:符合 KVC 仅意味着“遵循命名约定”。为什么这很重要?我可以将我的访问器方法称为任何我喜欢的名称。对于属性“Foo”:

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

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

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

-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':

- (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.

迷爱 2024-12-26 06:54:55

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

----- update

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

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

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"];
刘备忘录 2024-12-26 06:54:55

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

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

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文