Advertisements

Extension 14: Advanced KVC


Last week’s Lesson covered the basics of KVC, and it is those features that would be used 90% of the time. But KVC has some more to offer. Let’s take a look.

Batch Processing

Another one of KVC’s methods is dictionaryWithValuesForKeys:. The single argument is an array of strings. From that, the invokes valueForKey: with each key, and returns a dictionary with the keys and values. For example, to get some attributes of a piece of merchandise from our hypothetical store, we could use the following code:

Merchandise *product = [[store valueForKeyPath:@"merchandise"] lastObject];	// Last object in array
NSArray *keys = [NSArray arrayWithObjects: @"brand", @"price", @"department", @"shelf", @"netWeight", nil];
NSDictionary *productInfo = [product dictionaryWithValuesForKeys:keys];

You could then use this dictionary in an inventory tracking program, for example.

This method also has a counterpart, setValuesForKeysWithDictionary:. Called on an instance of any object, this method goes through each key in the dictionary, and replaces that key’s value in the object with the new value.

nil Values

Here is one minor issue that you might run into with KVC. You can’t put nil into a dictionary (or array for that matter), because nil tells the collection that it’s the end of data. Therefore, you have to use [NSNull null] instead, and that’s the value you’ll get back if you call valueForKey: on an object type. But what happens if you try to set nil for a scalar type, such as an integer? By default, you get an error at runtime. Therefore, you have to override setNilValueForKey: and define your own implementation. In our store, the method might look like this:

- (void)setNilValueForKey:(NSString *)key {
	if ([key isEqualToString:@"price"])
		[self setValue:[NSNumber numberWithInt:0] forKey:@"price"];
	else
		[super setNilValueForKey:key];
}

Error Handling

What happens if you try to access or set a value for a key that doesn’t exist? In general, you get the compiler or runtime warning that looks like “this class is not key value coding-compliant for the key someKeyThatDoesn’tExist.” Fortunately, when KVC encounters this it will ask the class what to do. As such, there are two methods that you can override: valueForUndefinedKey: and setValue:forUndefinedKey:.

A simple way to handle this issue is to simply tell the user that the key is invalid. So to protect our store from crashes, we’re going to just do that:

- (void)setValue:(id)value forUndefinedKey:(NSString *)key {
	NSLog(@"Cannot set anything for this key. The key %@ is not valid.", key);
}

- (void)valueForUndefinedKey:(NSString *)key {
	NSLog(@"Cannot get value for this key. The key %@ is not valid.", key);
}

Obviously, KVC is a very powerful feature, and allows you to build very robust, abstract applications. In fact, it is the core data access mechanism in Core Data, Apple’s framework for accessing data from a database. But that’s a complex topic for another day.

Advertisements
Leave a comment

2 Comments

  1. Ryan

     /  July 6, 2011

    -setNilValueForKey should _never_ set an ivar explicitly; this is clearly documented in the KVC programming guide (http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/KeyValueCoding/Articles/AccessorConventions.html). If you don’t use -setValue:forKey:, registered observers of that property will not be notified it’s value was changed, and will break KVO.

    Reply
  1. Learn Objective-C in 24 Days « Programming for iOS

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

Advertisements
  • Welcome

    My goal is to make CupsOfCocoa into a beautiful source for beginners to the iPhone platform to get started. Subscribe below for more, and stay tuned!

  • Contact Me

    If you need to contact me for any reason, feel free to send me an email.
  • The Giving Spirit

    If you've found this site helpful, would you consider donating a little sum? Any amount is appreciated...Thanks so much!

  • Roadmap

  • Enter your email address to follow this blog and receive notifications of new posts by email.

    Join 222 other followers

  • Back to the Past

    May 2011
    S M T W T F S
    « Apr   Jun »
    1234567
    891011121314
    15161718192021
    22232425262728
    293031  
  • Time Machine

  • You count!

    • 621,662 views
  • Worldwide Stats

    free counters
  • Advertisements
%d bloggers like this: