Brief Intro to Key Value Coding

来源:互联网 发布:淘宝有哪些好吃的零食 编辑:程序博客网 时间:2024/06/06 09:16

这章是简略介绍KVC的Advantage和简单用法;确实不错,简单易懂,配合前一篇的定义,面试回答更有底气啦 ^ ^


Key-Value Coding

As stated earlier, key-value coding is a mechanism for accessing an object’s properties. In Chapter 2 of this book, you learned that properties encapsulate an object’s internal state. This state is not accessed directly, but rather using properties’ accessor methods (also known as getter andsetter methods). The compiler can generate these methods automatically (according to the property declaration). This reduces the amount of code to write and also facilitates program consistency and maintainability. In the following code fragment, a class named Hello declares a property named greeting of type NSString.

@interface Hello : NSObject@property NSString *greeting;...@end

This property can be accessed using either standard property accessors or dot notation syntax (recall that the compiler transforms property dot notation expressions into their corresponding accessor method invocations). Given aHello instance named helloObject, the value for thegreeting property can be retrieved using either of the following expressions:

[helloObject greeting]helloObject.greeting

Conversely, the value for the greeting property can be set using either of the following expressions:

[helloObject setGreeting:newValue]helloObject.greeting = newValue

Recall that a property's backing instance variable can also be accessed directly if the object associated with the property is not fully constructed (i.e., if the variable is accessed within a class init or dealloc method). Theinit method for the Hello class accesses the backing instance variable of the greeting property in Listing 18-1.

Listing 18-1.  Accessing a Property’s Backing Instance Variable

@implementation Hello- (id)init{  if ((self = [super init]))  {    _greeting = @"Hello";...}

Note that these mechanisms for accessing a property arecompile-time expressions, and hence tightly couple the calling code to the receiver object. With that background, you can now examine key-value codingIn a nutshell, it provides a key-value pair mechanism for accessing a property, where the key is the property’s name and thevalue is the property value. Now this mechanism should already be familiar to you, as it is identical to that used to access entries in a dictionary (e.g., an NSDictionaryinstance). For example, given a Hello instance namedhelloObject, the following expression uses key-value coding APIs to retrieve the value of the greeting property.

[helloObject valueForKey:@"greeting"]

Observe that the key provided is the name of the property, in this case greeting. Key-value coding APIs can also be used to set the value for the greeting property.

[helloObject setValue:@"Hello" forKey:@"greeting"]

OK, so this is all fine and good, but you may still be wondering, “What’s the advantage of using KVC to access properties versus the standard property accessor methods?” Well to begin with, key-value coding allows you to access a property using a string that can be varied at runtime, and thus provides a more dynamic, flexible approach for accessing and manipulating an object’s state. The following are several of the key benefits to key-value coding:

  • Configuration-based property access. KVC enables your code to access properties using a parameter-driven, common API.
  • Loose coupling. Use of KVC for property access reduces coupling between software components, thereby improving software maintainability.
  • Simplifies code. KVC can reduce the amount of code that you have to write, particularly in scenarios where you need to access a specific property based on a variable. Instead of using conditional expressions to determine the correct property accessor method to invoke, you can employ one KVC expression using the variable as its parameter.

Let’s say that you need to dynamically update the state of a model based on an input from the user. Listing 18-2provides an implementation of this logic using standard property accessors.

Listing 18-2.  Updating Model State Using Standard Property Accessors

- (void)updateModel:(NSString *)value forState:(NSString *)state{  if ([state isEqualToString:@"species"])  {    [self setSpecies:value];  }  else if ([state isEqualToString:@"genus"])  {    [self setGenus:value];  }  ...}

As shown in Listing 18-2, this method uses conditional expressions and standard property accessors to update the value of the correct property. Although functional, this implementation doesn’t scale well and is difficult to maintain because the code must be updated whenever the property names and/or number of properties changes. Contrast that with Listing 18-3, which implements the same logic using key-value coding.

Listing 18-3.  Updating Model State Using Key-Value Coding

- (void)updateModel:(NSString *)value forState:(NSString *)state{  [self setValue:value forKey:state];}

Comparing the two listings, it should be pretty obvious to you that the KVC-based implementation is a vast simplification over the earlier approach. As shown in Listing 18-3, KVC can greatly reduce the amount of code that you have to write to implement this type of logic. Compared toListing 18-2, it is also easier to both maintain and evolve because changing the properties of the model does not require any updates to the method (shown in Listing 18-3) that uses KVC.

Keys and Key Paths

Key-value coding uses keys and key paths for property access. key is a string that identifies a specific property.key path specifies a sequence of object properties to traverse. The KVC APIs support accessing both individual and multiple properties of an object. The properties can be object types, basic types, or C structs; basic types and structs are automatically wrapped to/from corresponding object types.

Just as dot notation syntax enables you to traverse nested properties in an object graph, KVC provides this capability through key paths. As an example, imagine a Person class that declares a property named name of type Name, and theName class declares a property named firstName of typeNSString (see Figure 18-1).

9781430250500_Fig18-01.jpg

Figure 18-1. Person object graph

The object-oriented principle of composition is used here to create an object graph comprised of a Person object that has a Name instance and an Address instance. Given this object graph, for a Person instance named person, dot notation syntax could be used to retrieve the value of thefirstName property, and then set the value of thefirstName property as follows:

person.name.firstName = @"Bob";

The key-value coding mechanism includes an API that provides the same functionality (i.e., thesetValue:forKeyPath: method). Its arguments include a key path that also uses dot notation.

[person setValue:@"Bob" forKeyPath:@"name.firstName"];

The valueForKeyPath: API would be used to retrieve a property value specified by a key path, for example

NSString *name = [person valueForKeyPath:@"name.firstName"];

As indicated earlier, key-value coding includes APIs for accessing multiple properties of an object. In the object graph depicted in Figure 18-1, a Person class declares aName property and an Address property. Key-value coding can be used to retrieve the keys and corresponding values for an input collection of keys. Listing 18-4 uses the KVCdictionaryWithValuesForKeys: method to retrieve the keys and values for the name and address properties of aPerson instance named person.

Listing 18-4.  Using KVC to Retrieve Multiple Property Values

NSArray *personKeys = @[@"name", @"address"];NSDictionary *personValues = [person dictionaryWithValuesForKeys:personKeys];

Conversely, Listing 18-5 uses the KVCsetValuesForKeysWithDictionary: method to set values for the name and address properties of a Person instance named person.

Listing 18-5.  Using KVC to Set Multiple Property Values


Name *tom = [Name new];Address *home = [Address new];NSDictionary *personProperties = @{@"name":tom, @"address":home};[person setValuesForKeysWithDictionary:personProperties];

These are just some of the features that key-value coding provides. In the following paragraphs, you will examine this technology in more detail and learn some of its more advanced features.


原创粉丝点击