valueforKey:,objectForKey:和valueForKeyPath之间的区别是什么?

时间:2010-12-20 12:38:39

标签: objective-c

我有两个问题:

  1. valueForKey:objectForKey:之间有什么区别?它是NSDictionary s(objectForKey:)而其他人是valueforKey:,还是反过来?

  2. valueForKey:valueForKeyPath:之间有什么区别?它与Core Data有关吗?

  3. 请帮忙。

3 个答案:

答案 0 :(得分:61)

valueForKey:是NSKeyValueCoding协议的一部分,因此是键值编码框架的一部分,它允许您在运行时按名称访问类属性。例如,加载NIB的方式是 - 加载与连接关联的属性的名称,然后直接按名称设置值。这与可视化界面设计工具通常在其他语言中工作的方式形成对比,产生大量隐藏的静态编译代码。

objectForKey:仅在字典上定义,并通过其键查找对象。 NSDictionary是一个存储值和键之间连接的类。

因此,可以在NSDictionary上使用valueForKey:来返回有关字典的元信息,例如其中的对象计数,所有键的列表等。objectForKey:将实际使用查看字典。

在运行时,不同之处在于objectForKey:是一个完全不透明的实现方法。 valueForKey:显式依赖于随后调用命名的getter和setter。后者的原因是您可以将键值编码扩展到键值观察,您可以在每次特定对象的特定属性发生变化时通知您。在运行时,通过方法swizzle实现,其中原始setter被调用前一个setter的新setter替换,然后发送所需的消息。因为所有消息都是动态分派的,所以这只是通过修改对象实例中的表来实现的。

因此,任何符合键值编码的对象(这意味着以正确的方式声明和实现属性,new-ish @ property / @ synthesize语法自动执行)都可以在没有对象本身必须的情况下被观察到实施任何代码。

还有一些苹果公司的东西使用键值编码来实现各种各样的东西,包括CoreData,但它不是专门用于启用任何其他技术。

valueForKeyPath:valueForKey:类似,只是它可以遍历多个对象。因此,您可以拥有一组具有一堆属性的根对象,每个属性都是具有另一组属性的另一个对象,并且使用键路径可以在该数据结构的叶子处检索值,而不是为自己迭代对象之后的对象。

总之,valueForKey:valueForKeyPath:提供有关对象实例的信息,并与Objective-C运行时的动态特性进行交互。 objectForKey:是一种执行字典任务的字典特定方法。

加法:

一个例子,编码为I类型并假设NSDictionary符合键值编码:

NSDictionary *someDictionary;
// create someDictionary, populate it, for example (note: we assume photoOfKeys.jpg
// definitely exists, not a good idea for production code — if it doesn't we'll get
// a nil there and anything after it won't be added to the dictionary as it'll appear
// that we terminated the list):
someDictionary = @{ @"favouriteGarment": @"hat",
                    @"@allKeys"        : [NSImage imageNamed:NSImageNameDotMac],
                    @(2)               : NSArray.new };

NSObject *allKeys; 
// we make no assumptions about which type @allKeys will be,  but are going to assume
// we can NSLog it, so it needs to be a descendant of NSObject rather than 'id' so as 
// to definitely respond to the 'description' message — actually this is just compile
// time semantics, but if someone else reads this code it'll make it obvious to them 
// what we were thinking...

// some code to get all of the keys stored in the dictionary and print them out;
// should print an array containing the strings 'favouriteGarment', '@allKeys' and
// the number 2
allKeys = [someDictionary valueForKey:@"@allKeys"];
NSLog(@"%@", allKeys);

// some code to get the object named '@allKeys' from the dictionary; will print
// a description of the image created by loading photoOfKeys.jpg, above
allKeys = [someDictionary objectForKey:@"@allKeys"];
NSLog(@"%@", allKeys);
// `objectForKey is analogous to `objectForKeyedSubscript:`, aka
allKeys = someDictionary[@"@allKeys"];

allKeys是NSDictionary的一个属性,如here所述。我还添加了从NSString allKeys到一些键的照片的映射。我是否使用键值编码valueForKey:方法或NSDictionary objectForKey:查找方法指示我是否读取对象实例的属性,或者是否向对象实例发送一条消息,要求它执行其独特的工作

答案 1 :(得分:17)

  1. objectForKey:NSDictionary上用于访问与密钥关联的对象的方法。 valueForKey:NSObject上的一种方法,用于通过访问器方法,属性和/或实例变量的名称访问与任何对象关联的任何值。
  2. valueForKeyPath:可以看作是对valueForKey:的多次调用的简写。如果你愿意的话,你可以把它想象成一个xpath。
  3. 这两个语句将产生相同的输出:

    // Using nested valueForKey:
    NSLog(@"%@", [[myObject valueForKey:@"foo"] valueForKey:@"bar"]);
    // Can be done with a single valueForKeyPath;
    NSLog(@"%@", [myObject valueForKeyPath:@"foo.bar"]);
    

    valueForKey:valueForKeyPath:是KVC(键值编码)的一部分。可以在此处找到介绍和深入的文档:http://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/KeyValueCoding/

答案 2 :(得分:1)

  1. valueForKey:valueAtKeyPath:NSKeyValueCoding非正式协议中定义的方法,两者的默认实现均由根类NSObject提供。

    objectForKey:NSDictionary上的方法。

  2. valueForKey:获取属性的键,而valueAtKeyPath:获取所谓的keypath。密钥路径是指向特定属性的句点分隔路径,例如@"relationship.property"