Online Book Reader

Home Category

Objective-C Programming_ The Big Nerd Ranch Guide - Aaron Hillegass [75]

By Root 499 0
error. Make this mistake in main.m:

NSLog(@"the product name is %@", [a valueForKey:@"productNammmme"]);

When you build and run it, you will see an error:

*** Terminating app due to uncaught exception 'NSUnknownKeyException',

reason: '[ valueForUndefinedKey:]:

this class is not key value coding-compliant for the key productNammmme.'

Fix the error before you go on.

Why is key-value coding interesting? Anytime a standard framework wants to push data into your objects, it will use setValue:forKey:. Anytime a standard framework wants to read data from your objects, it will use valueForKey:. For example, Core Data is a framework that makes it easy to save your objects to a SQLite database and then bring them back to life. It manipulates your custom data-bearing objects using key-value coding.

To prove that key-value coding will manipulate your variables even if you have no accessors, comment out the @property declaration for productName in Appliance.h:

#import

@interface Appliance : NSObject {

NSString *productName;

int voltage;

}

// @property (copy) NSString *productName;

@property (nonatomic) int voltage;

// The designated initializer

- (id)initWithProductName:(NSString *)pn;

@end

Also, remove all use of the methods setProductName: and productName from Appliance.m:

@implementation Appliance

@synthesize voltage;

- (id)initWithProductName:(NSString *)pn

{

self = [super init];

if (self) {

productName = [pn copy];

[self setVoltage:120];

}

return self;

}

- (id)init

{

return [self initWithProductName:@"Unknown"];

}

- (NSString *)description

{

return [NSString stringWithFormat:@"<%@: %d volts>", productName, voltage];

}

@end

Build and run the program. Note that even though you have no accessor methods for productName, the variable can still be set and read from other methods. This is an obvious violation of the idea of object encapsulation – methods of an object are public, but the instance variables are delicate and should be kept private. If key-value coding weren’t astonishingly useful, no one would tolerate it.

Non-object types

The key-value coding methods are designed to work with objects, but some properties hold a non-object type, like an int or a float. For example, voltage is an int. How do you set voltage using key-value coding? You use an NSNumber.

In main.m, change the line for setting the voltage from this:

[a setVoltage:240];

to this:

[a setValue:[NSNumber numberWithInt:240] forKey:@"voltage"];

Add an explicit accessor to Appliance.m so that you can see it getting called:

- (void)setVoltage:(int)x

{

NSLog(@"setting voltage to %d", x);

voltage = x;

}

Build and run the program.

Similarly, if you ask for the valueForKey:@"voltage", you will get back an NSNumber containing the value of voltage.

31

Categories


Categories let a programmer add methods to any existing class. For example, Apple gave us the class NSString. We don’t get the source code to that class, but categories give us the ability to add new methods to NSString.

Create a new Foundation Command Line Tool called VowelCounter. Then create a new file that is an Objective-C category. Name the category VowelCounting and make it a category on NSString.

Now open NSString+VowelCounting.h and declare a method that you want to add to the NSString class:

#import

@interface NSString (VowelCounting)

- (int)vowelCount;

@end

Now implement the method in NSString+VowelCount.m:

#import "NSString+VowelCounting.h"

@implementation NSString (VowelCounting)

- (int)vowelCount

{

NSCharacterSet *charSet =

[NSCharacterSet characterSetWithCharactersInString:@"aeiouyAEIOUY"];

NSUInteger count = [self length];

int sum = 0;

for (int i = 0; i < count; i++) {

unichar c = [self characterAtIndex:i];

if ([charSet characterIsMember:c]) {

sum++;

}

}

return sum;

}

@end

Now use the new method in main.m:

#import

#import "NSString+VowelCounting.h"

Return Main Page Previous Page Next Page

®Online Book Reader