2010-12-20 50 views
34

我有2个问题:valueforKey:,objectForKey :,和valueForKeyPath:有什么区别?

  1. 是什么valueForKey:objectForKey:之间的区别?是NSDictionary s(objectForKey:),其他人是valueforKey:,还是相反?

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

请帮忙。

+3

类似的问题 http://stackoverflow.com/questions/1062183/objective-c-whats-the-difference-between-objectforkey-and-valueforkey – Gyani 2010-12-20 13:00:47

回答

59

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

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

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

在运行时,区别在于objectForKey:是一种完全不透明实现的方法。 valueForKey:明确依赖于随后调用命名的getters和setter。后者的原因是您可以将键值编码扩展到键值观察,您可以在每次特定对象上的某个特定属性发生变化时要求通知键值。在运行时,可以通过调用方法来实现,其中原来的setter被新调用者替换,然后发送出所需的消息。由于所有消息都是动态分发的,只需通过修改对象实例中的表来实现。因此,任何符合键值编码的对象(只是意味着以正确的方式声明和实现属性,新的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是如所描述的here的NSDictionary的性质。我还添加了NSString allKeys到某些键的照片的映射。无论我使用键值编码valueForKey:方法还是NSDictionary objectForKey:查找方法都指示是否读取对象实例的属性,或者是否向对象实例发送消息,要求其执行其唯一作业。

+0

我对使用valueForKey:和objectForKey:on字典有点困惑。当你说valueForKey可以在NSDictionary上用来返回关于字典的元信息,比如它里面的对象的数量,所有键的列表等等。 能不能请你用一个例子来展示它会返回什么所以我对这个区别有点清楚。 – hmthur 2010-12-20 13:50:44

+0

@hmthur Theres一些很好的例子[这里](http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/KeyValueCoding/Concepts/ArrayOperators.html%23//apple_ref/doc/uid/20002176 -BAJEAIEEhttp://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/KeyValueCoding/Concepts/ArrayOperators.html%23//apple_ref/doc/uid/20002176-BAJEAIEE) – 2010-12-20 14:00:36

+1

我想@“allKeys”在示例中应该是@“@ allKeys”。 – 2011-10-05 17:35:46

1
  1. valueForKey:valueAtKeyPath:处于NSKeyValueCoding非正式协议中定义的方法,以及由根类NSObject提供了用于既默认实现。

    objectForKey:是在NSDictionary上的方法。

  2. valueForKey:需要一个属性的密钥,而valueAtKeyPath:需要一个所谓的keypath。关键路径是特定属性的句点分隔的路径,如@"relationship.property"

17
  1. objectForKey:是用于访问与关键字相关联的对象的方法,其中NSDictionaryvalueForKey:NSObject上的一种方法,用于通过访问方法,属性和/或实例变量的名称访问与任何对象关联的任何值。
  2. valueForKeyPath:可以看作是对valueForKey:的几个呼叫的简写。如果你愿意的话,你可以把它看作xpath的一种。

这两条语句将导致相同的输出:

// 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/