setValue:ForKey:而不是set(无论如何)?

时间:2016-02-18 04:59:35

标签: ios objective-c cocoa methods

在Objective-C中,我知道有多种方法可以为属性(或键)设置值。如果给定属性的名称是“foo”,我将主要执行以下操作:

[object setFoo:@"value"];

甚至是:

object.foo = @"value";

但是,在某些情况下,我看到了他们使用此代码的代码:

[object setValue:@"value" forKey:@"foo"];

这两种方法之间的确切区别是什么(Xcode为您自动填充第一种方法的事实除外)?

另外,使用第二种方法是否安全?(setValue:forKey :)

感谢您抽出宝贵时间阅读此问题。非常感谢你的帮助。

2 个答案:

答案 0 :(得分:2)

以下是根据Apple官方文档的键值编码的定义:

键值编码是一种间接访问对象属性的机制,使用字符串来标识属性,而不是通过调用访问器方法或直接通过实例变量访问它们。

让我们通过一些简单的例子看到它:

假设我们有一个名为firstname的属性,我们想要为它赋值John。通常,我们在代码中编写的内容是:

self.firstname = @"John";

或者这个:

_firstname = @"John";

很熟悉吧?现在,使用KVC机制,上面的分配看起来像下一个:

[self setValue:@"John" forKey:@"firstname"];

如果仔细观察,这看起来类似于我们将值设置为字典的方式,或者将标量值和结构转换为NSValue对象时的方式。如您所见,我们为关键名字设置值John。还有一个例子:

[someObject.someProperty setText:@"This is a text"];

使用KVC:

[self setValue:@"This is a text" forKeyPath:@"someObject.someProperty.text"];

在这两个示例中,不是直接将值(第一个示例)设置为属性或使用属性的setter方法(第二个示例),而是简单地将值与键或键路径匹配(更多关于键和键路径的信息)一会儿)。正如您所假设的那样,因为我们使用键和值,所以上述技术称为键值编码。

我希望你能了解这种方法及其不同之处。 :)

答案 1 :(得分:1)

[object setFoo:@"value"];

object.foo = @"value";

应该与编译器等效,基本上为两者生成相同的代码。

[object setValue:@"value" forKey:@"foo"];
但是,根本不同。它使用NSKeyValueCoding Protocol又名 KVC 。它的优点是这里的密钥是一个字符串,这意味着它可以动态确定(例如从一些配置文件或类似文件中获取)。但也存在一些缺点:

  • 编译器无法检查@"key"是否为object的有效属性。这意味着如果不是,那么在运行时(也就是崩溃或RUT:快速非预定终止)会导致异常。

  • 有点慢

内部KVC最终使用与上述相同的访问器。请参阅here for the Accessor Search Implementation Details