简体   繁体   English

键值编码和 NSDictionary 有什么区别?

[英]What's the difference between Key-Value Coding and NSDictionary?

What's the difference between Key-Value Coding and NSDictionary?键值编码和 NSDictionary 有什么区别? KVC has addValue:forKey and NSDicationary has addObject:forKey, which gives me the impression that they're very similar structures. KVC 有 addValue:forKey 和 NSDicationary 有 addObject:forKey,这给我的印象是它们是非常相似的结构。

What is Key-Value Coding? 什么是键值编码? :

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.键值编码是一种间接访问对象属性的机制,使用字符串来标识属性,而不是通过调用访问器方法或通过实例变量直接访问它们。 In essence, key-value coding defines the patterns and method signatures that your application's accessor methods implement.本质上,键值编码定义了应用程序的访问器方法实现的模式和方法签名。

NSDictionary Class Reference : NSDictionary类参考

The NSDictionary class declares the programmatic interface to objects that manage immutable associations of keys and values. NSDictionary类为管理键和值的不可变关联的对象声明了编程接口。

So,所以,

  • NSDictionary is an object, while key-value coding is a protocol NSDictionary是一个对象,而键值编码是一个协议
  • NSDictionary can store and retrieve objects, while key-value coding must rely on some other form of storage NSDictionary可以存储和检索对象,而键值编码必须依赖某种其他形式的存储

Key-Value Coding is commonly used with Key-Value Observation (see below), although there are other uses.键值编码通常与键值观察(见下文)一起使用,尽管还有其他用途。 For example:例如:

  • KVC allows you to string together properties in a string, even without importing those classes. KVC 允许您将属性串成一个字符串,即使不导入这些类。 (For example, to see my landlord's other tenants, you might retrieve aaronBrager.apartment.landlord.tenants ). (例如,要查看我房东的其他租户,您可以检索aaronBrager.apartment.landlord.tenants )。
  • KVC allows the use of collection operators like @avg , @sum , and @count . KVC 允许使用诸如@avg@sum@count类的集合运算符

If you're not sure what you should use, I suggest learning to use NSDictionary and basic model objects before you venture into KVC.如果您不确定应该使用什么,我建议您在尝试使用 KVC 之前学习使用NSDictionary和基本模型对象。

See also this Stack Overflow answer which reviews some of the syntax differences.另请参阅此 Stack Overflow 答案,其中回顾了一些语法差异。


Key-Value Observation键值观察

Commonly used with Key-Value Coding, Key-Value Observation allows your classes to be notified when the value of a particular key changes.通常与键值编码一起使用,键值观察允许您的类在特定键的值发生变化时得到通知。 (This is indirectly related to your question.) (这与您的问题间接相关。)

There are two areas where this gets really powerful:这在两个方面变得非常强大:

  1. You can use KVO to observe changes in collection objects可以使用 KVO 观察集合对象的变化
  2. With KVO, you can dynamically generate keys based on other keys :使用 KVO,您可以根据其他密钥动态生成密钥

     - (NSString *)fullName { return [NSString stringWithFormat:@"%@ %@",firstName, lastName]; } + (NSSet *)keyPathsForValuesAffectingValueForKey:(NSString *)key { NSSet *keyPaths = [super keyPathsForValuesAffectingValueForKey:key]; if ([key isEqualToString:@"fullName"]) { NSArray *affectingKeys = @[@"lastName", @"firstName"]; keyPaths = [keyPaths setByAddingObjectsFromArray:affectingKeys]; } return keyPaths; }

    Now anyone observing fullName will be notified when either lastName or firstName changes.现在,当lastNamefirstName更改时,任何观察fullName都会收到通知。

Key Value Coding is a set of conventions for accessing the contents of an object using string identifiers. 键值编码是一组使用字符串标识符访问对象内容的约定。 KVC compliant classes have properties that follow the KVC naming convention. KVC 兼容类具有遵循 KVC 命名约定的属性。 A number of different technologies are layered on top of KVC and depend on it to function.许多不同的技术都位于 KVC 之上,并依赖于它才能发挥作用。 KVC is implemented as an informal protocol on NSObject . KVC 是作为NSObject上的非正式协议实现的。 KVC can can be used with all descendants of NSObject, as long as the object's properties are compliant with the KVC naming conventions. KVC 可以用于 NSObject 的所有后代,只要对象的属性符合 KVC 命名约定。

NSDictionary , in contrast, is a Foundation collection class representing a class cluster.相反, NSDictionary是代表类簇的 Foundation 集合类。

KVC is a fundamental concept in Cocoa, the more you know about it the better your applications will be. KVC 是 Cocoa 中的一个基本概念,您对它了解得越多,您的应用程序就会越好。

I'll try to answer the exact question.我会尽量回答确切的问题。 the DIFFERENCE is, an NSDictionary holds arbitrary key-value pairs (eg @{ @"Oy":@"Vey", @"name":@"Motti" } but a normal NSObject descendant say:不同之处在于,一个 NSDictionary 包含任意键值对(例如@{ @"Oy":@"Vey", @"name":@"Motti" }但是一个普通的NSObject后代说:

@interface MyClass : NSObject {
  NSString *firstName;
  NSString *lastName;
}
@end
@implementation
- (id) init {
  firstName = "Bobo";
  lastName = "Link";
}
@end
 MyClass *myObj = [[MyClass alloc] init];

cannot usually be accessed via通常不能通过

 [myObj valueForKey:@"firstName"];

It is NOT a collection, and NOT key-value-coding compliant!它不是一个集合,也不符合键值编码!

Complying with KVC (per specific property) allows you to use an ObjC object AS IF it was an NSDictionary.遵守 KVC(根据特定属性)允许您像使用 NSDictionary 一样使用 ObjC 对象。 So if I changed the declaration of the object like thus:因此,如果我像这样更改对象的声明:

@interface MyClass : NSObject {
  NSString *lastName;
}
  @property (readwrite, strong, name=firstName) NSString *firstName;
@end

to make it KVC compliant only on firsName - then calling使其仅在firsName上符合 KVC - 然后调用

 [myObj valueForKey:@"firstName"];

would yield the expected value @"Bobo" .将产生预期值@"Bobo"

That's about the difference.这就是区别。 However, KVC goes well beyond allowing simple dictionary-like access to objects with key-value semantics.然而,KVC 远不止允许对具有键值语义的对象进行类似字典的简单访问。

It introduces the concept of keyPath , where you can "drill" through succession of objects and properties like in [myBankAccount valueForKeyPath:@"addresses.billingAddress.city"] , or to evaluate and extract collections of values "drilled" at keyPaths (eg [personObject valueForKeyPath:@"friends.firstName"] will collect an NSArray of firstNames of all your friends, provided that friends is a collection (say NSArray ) of Friend objects each having a KVC compliant property named firstName .它引入了keyPath的概念,您可以在其中“钻取”像[myBankAccount valueForKeyPath:@"addresses.billingAddress.city"]一系列对象和属性,或者评估和提取在 keyPaths 处“钻取”的值的集合(例如[personObject valueForKeyPath:@"friends.firstName"]将收集所有朋友的 firstNames 的 NSArray,前提是friendsFriend对象的集合(比如NSArray ),每个对象都有一个名为firstName的 KVC 兼容属性。

But it doesn't stop even there -- KVC provides special key-path elements (like @avg , @sum , SELF , @distinctUnionOfObjects and others) that when correctly used inside key paths allow for smart evaluation of accumulations and summaries of collected values, saving tons of loops and lines of codes.但它并不止@avg @sum提供了特殊的关键路径元素(如@avg@sumSELF@distinctUnionOfObjects等),当在关键路径中正确使用时,可以对收集的值的累积和摘要进行智能评估,节省大量的循环和代码行。 They also look fancy and are very readable.它们看起来也很花哨,并且非常具有可读性。 For example: [accounts valueForKeyPath:@"transactions.@avg.amount"] will scan all the accounts.例如: [accounts valueForKeyPath:@"transactions.@avg.amount"]将扫描所有帐户。 For each account it will again scan its transactions , collecting their amount .对于每个帐户,它将再次扫描其transactions ,收集其amount It will then average the amounts of all transactions of an account, and will finally collect and return an NSArray of NSNumber s, containing average-amounts per account.然后它将平均一个帐户的所有交易金额,并最终收集并返回一个NSNumberNSArray ,其中包含每个帐户的平均金额。 That's concise and powerful coding.这是简洁而强大的编码。

Other answers already provide lots of good links for documentation.其他答案已经提供了很多很好的文档链接。

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

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