KVC和Properties有什么区别?

时间:2011-11-19 02:19:12

标签: objective-c cocoa key-value-coding

所以,我已经阅读了注释文档

  

Objective-C 2.0的点语法和键值编码是正交技术。无论是否使用点语法,都可以使用键值编码,无论是否使用KVC,都可以使用点语法。但是,两者都使用“点语法”。在键值编码的情况下,语法用于分隔键路径中的元素。重要的是要记住,当您使用点语法访问属性时,您将调用接收器的标准访问器方法。

然后提供了一个例子,据说显示了两者之间的差异。但是,我仍然没有得到,KVC和属性访问器方法有什么区别?他们不一样吗?我如何区分调用setValue:forKeyPath:和简单访问器的点?

2 个答案:

答案 0 :(得分:15)

  

但是,我仍然没有得到,KVC和属性访问方法有什么区别?

KVC是一种调用属性访问器方法或以其他方式访问属性的方法。

“否则访问”是什么意思?对于KVC目的,没有访问器方法的实例变量计为非正式属性。如果找不到匹配的访问者对,它将直接获取或设置实例变量的值。 (是的,这在现代代码中不值得使用。总是为你打算在其他地方访问的任何内容声明@property,反之,不要使用KVC访问任何不属于公共属性的东西。)< / p>

属性访问器方法是KVC在它们存在时将调用的方法(首选,由KVC和每个理智的程序员,通过直接的ivar访问)。访问者可以获取或设置实例变量,如合成访问者那样,或访问其他存储。

访问器是实现,属性是接口,KVC是使用它们的一种方式。

  

我如何区分调用setValue:forKeyPath:和简单访问器的点?

键路径是字符串,而属性访问表达式是表达式。编译器评估属性访问表达式并将其转换为一个或多个Objective-C消息,而KVC在运行时评估密钥路径。

因此,当您使用密钥路径时:

[someObject setValue:theValue forKeyPath:@"foo.bar.baz"];

你知道它是一个关键路径,因为(1)它是一个字符串,在本例中由字符串文字语法@"…"表示,以及(2)你将密钥路径字符串传递给{{ 1}}让它来评估。

使用密钥路径使用KVC访问命名属性。它将代表您发送任何相关的访问者消息。

使用属性访问表达式时:

setValue:forKeyPath:

您知道它是属性访问表达式,因为您没有使用字符串标识属性。您正在自己的代码中访问它们(发送访问者消息)。

没有太多理由以任何形式使用KVC;当你在作者/编译时知道属性时,最好声明someObject.foo.bar.baz = theValue; 并自己访问属性,无论是属性访问表达式还是消息表达式(@property)。使用KVC的时间是在运行时间之前您不知道要访问哪个属性,这是非常罕见的。它主要是KVO背后的构建块技术,Cocoa Bindings,Core Animation的部分等等。

大多数情况下,您只想自己访问属性。

答案 1 :(得分:2)

键值编码允许您使用属性的字符串名称通过代码设置和获取属性的值。例如,如果我有一个名为foo的属性,其类型为NSString:

[self setValue:@"mystring" forKey:@"foo"];

// read the value by key
NSString *s =  [self valueForKey:@"foo"];

Dot语法是编译语法糖。作为个人偏好(有些人不同意 - 很好)我不使用点语法,但我仍然使用KVC:

[myObj setFoo: @"someString"]

等于:

myObj.foo = @"someString";

它们是正交的,不同的概念,但都涉及与属性交互的方式

最后,您提到了属性语法。另一个正交概念,但与处理属性有关。

使用objective-c,约定很重要。跟着他们。属性是赋值的get和set [Name]属性的名称:

- (NSString*)foo
{
    return _foo;  // defined as (NSString*)_foo in header
}

- (void) setFoo: (NSString*)foo
{
    if (foo == _foo)
        return;

    NSString* curr = _foo;

    _foo = [foo retain];
    [curr release];    
}

现在,谁愿意每次都写这样的东西。所以,输入@property语法:

在标题中:

@property (retain) NSString *foo;

然后在.m:

@synthesize foo;

这相当于手写的属性访问器。它是编译器语法糖,它根据属性的属性扩展属性代码。

文档:

http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/KeyValueCoding/Articles/KeyValueCoding.html

http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/ObjectiveC/Chapters/ocProperties.html