简体   繁体   English

setValue:ForKey:而不是set(whatever)?

[英]setValue:ForKey: instead of set(whatever)?

In Objective-C, there are various ways to set a value for a property(or a key) as I know. 据我所知,在Objective-C中,有多种方法可以为属性(或键)设置值。 If a given property's name is "foo", I would primarily do something like: 如果给定属性的名称为“ foo”,则我主要要做的是:

[object setFoo:@"value"];

or even something like: 甚至类似:

object.foo = @"value";

However, in some cases, I have seen codes where they use this instead: 但是,在某些情况下,我看到了一些代码使用它们代替它们:

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

What is the exact difference between those two methods(except for the fact that Xcode autocompletes the first method for you)? 这两种方法之间的确切区别是什么(除了Xcode为您自动完成第一个方法的事实)?

Plus, is it even safe to use the second method?(setValue:forKey:) 另外,使用第二种方法是否更安全?(setValue:forKey :)

Thank you for taking your time to read this question. 感谢您抽出宝贵的时间阅读此问题。 I appreciate your help a lot. 非常感谢您的帮助。

Here is the definition of the Key-Value Coding according to Apple's official documentation: 根据苹果公司的官方文档,这是键值编码的定义:

Key-value coding is a mechanism for accessing an object's properties indirectly, using strings to identify properties, rather than through invocation of an accessor method or accessing them directly through instance variables. 键值编码是一种机制,用于间接访问对象的属性,而不是通过调用访问器方法或通过实例变量直接访问它们,而是使用字符串来标识属性。

let's see it through some simple examples: 让我们通过一些简单的例子来看一下:

Let's suppose that we have a property named firstname, and we want to assign the value John to it. 假设我们有一个名为firstname的属性,并且想为其分配值John。 Normally, what we would write in code to do it is this: 通常,我们将用代码编写的代码是这样的:

self.firstname = @"John";

or this: 或这个:

_firstname = @"John";

Quite familiar, right? 很熟悉吧? Now, using the KVC mechanism the above assignment would look like the next one: 现在,使用KVC机制,以上任务将类似于下一个任务:

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

If you look closely, this looks similar to the way we set values to dictionaries, or when converting scalar values and structs to NSValue objects. 如果仔细观察,这类似于我们将值设置为字典的方式,或者将标量值和结构转换为NSValue对象时的方式类似。 As you see, we set the value John for the key firstname. 如您所见,我们将键名设置为John值。 One more example: 再举一个例子:

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

Using KVC: 使用KVC:

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

In both of these examples, instead of directly setting the value (first example) to the property or use the setter method (second example) of the property, we simply match values to keys or keypaths (more about keys and keypaths in just a moment). 在这两个示例中,我们没有直接将值(第一个示例)设置为属性或使用属性的setter方法(第二个示例),而是简单地将值与键或键路径匹配(有关键和键路径的更多信息) )。 As you assume, because we use keys and values, the above technique is called Key-Value Coding. 如您所料,由于我们使用键和值,因此上述技术称为键值编码。

I hope you will get idea about this methods and its difference. 希望您能对这种方法及其区别有所了解。 :) :)

[object setFoo:@"value"];

and

object.foo = @"value";

should be equivalent with the compiler basically generating the same code for both. 应该与编译器等效,基本上为两者生成相同的代码。

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

however is fundamentally different. 但是根本不同。 It uses the NSKeyValueCoding Protocol aka KVC . 它使用NSKeyValueCoding协议 (又名KVC) It's advantage is that the key here is a string, that means it can be dynamically determined (for example taken from some configuration file or similar). 优点是这里的键是一个字符串,这意味着可以动态确定它(例如,从某些配置文件或类似文件中获取)。 But there are some downsides too: 但是也有一些缺点:

  • The compiler can not check if @"key" is a valid property of object . 编译器无法检查@"key"是否是object的有效属性。 That means if it isn't, you'll end up with an exception during runtime (aka crash or RUT: Rapid Unscheduled Termination). 这意味着,如果不是这样,您将在运行时遇到异常(aka崩溃或RUT:快速计划外终止)。

  • It is somewhat slower 有点慢

Internally KVC ends up using the same accessors as mentioned above. 在内部,KVC最终使用与上述相同的访问器。 See here for the Accessor Search Implementation Details . 有关访问者搜索实现的详细信息,请参见此处

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM