01.02.2014 Views

Objective-C Fundamentals

Objective-C Fundamentals

Objective-C Fundamentals

SHOW MORE
SHOW LESS

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

218 CHAPTER 11 Key-Value Coding and NSPredicate<br />

}<br />

}<br />

[super setValue:value forUndefinedKey:key];<br />

- (id)valueForUndefinedKey:(NSString *)key {<br />

if ([key isEqualToString:@"advert"]) {<br />

return [NSString stringWithFormat:@"$%f, %@",<br />

rentalPrice, address];<br />

} else {<br />

[super valueForUndefinedKey:key];<br />

}<br />

}<br />

An important point to consider about custom setValue:forUndefinedKey: and value-<br />

ForUndefinedKey: message implementations is that, internally, they should access setter<br />

methods or properties rather than their backing ivars directly. If you access or<br />

update an instance variable directly, Key-Value Observing won’t always correctly detect<br />

changes in a key’s value and hence won’t notify interested observers. In listing 11.1,<br />

therefore, it’s important that you refer to rentalPrice and address as self.rental-<br />

Price and self.address because, instead of updating the instance variable, this syntax<br />

(or the alternative [self rentalPrice], [self address]) will invoke the matching<br />

setter methods giving KVO a chance to observe the change.<br />

With the additional method implementations in listing 11.1, the CTRentalProperty<br />

object now appears to have an additional property called advert that returns a string<br />

in the format "$price, address"—for example, "$175, 46 Coleburn Street". Following<br />

is an example of how this property would be accessed:<br />

NSLog(@"Rental price is: %@", [house valueForKey:@"rentalPrice"]);<br />

NSLog(@"Address is: %@", [house valueForKey:@"address"]);<br />

NSString *advert = [house valueForKey:@"advert"];<br />

NSLog(@"Advert for rental property is '%@'", advert);<br />

This is not a very realistic implementation of the setValue:forUndefinedKey: and<br />

valueForUndefinedKey: messages. It would have perhaps been easier, more efficient,<br />

and cleaner to add a physical property named advert to the CTRentalProperty class. A<br />

more realistic implementation could use something like an NSMutableDictionary to<br />

enable a CTRentalProperty object to store arbitrary metadata about a rental property.<br />

11.2.2 Handling nil values<br />

A similar problem can occur when a nil value is passed to setValue:forKey:. As an<br />

example, what happens if you execute the following statement?<br />

[house setValue:nil forKey:@"rentalPrice"];<br />

Because the rentalPrice property of the CTRentalProperty class is a primitive datatype<br />

(float), it can’t store the value nil. In this case, the default behavior is for the KVC<br />

infrastructure to throw an exception, as follows:<br />

[ setNilValueForKey]: Could not set nil as the<br />

value for the key rentalPrice.

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!