【问题标题】:setValue:ForKey: instead of set(whatever)?setValue:ForKey: 而不是 set(whatever)?
【发布时间】:2016-05-30 03:08:27
【问题描述】:

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

[object setFoo:@"value"];

甚至类似:

object.foo = @"value";

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

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

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

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

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

【问题讨论】:

    标签: ios objective-c cocoa methods


    【解决方案1】:

    根据苹果官方文档,Key-Value Coding 的定义如下:

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

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

    假设我们有一个名为 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 方法(第二个示例),而是简单地将值匹配到键或键路径(有关键和键路径的更多信息在一会儿)。正如您所假设的,因为我们使用键和值,所以上述技术称为键值编码。

    我希望您能了解这种方法及其区别。 :)

    【讨论】:

    • _firstname = @"John"; 没有使用 KVC 机制。不要混淆。
    【解决方案2】:
    [object setFoo:@"value"];
    

    object.foo = @"value";
    

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

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

    然而本质上是不同的。它使用NSKeyValueCoding Protocol aka KVC。它的优点是这里的键是一个字符串,这意味着它可以动态确定(例如从一些配置文件或类似文件中获取)。但也有一些缺点:

    • 编译器无法检查@"key" 是否是object 的有效属性。这意味着如果不是,您将在运行时遇到异常(又名崩溃或 RUT:快速未计划终止)。

    • 有点慢

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-10-31
      • 2019-07-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-10-21
      相关资源
      最近更新 更多