Online Book Reader

Home Category

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

By Root 493 0
of NSObject can do. And instances of NSObject respond to init messages. However, it causes a problem here because the above line of code creates an instance of Appliance that has nil for a product name and zero for voltage. And we decided earlier that every instance of Appliance needs a voltage of 120 and an actual name to function correctly. How can you prevent this from happening?

The solution is simple. In Appliance.m, add an init method to call initWithProductName: with a default value for the name.

- (id)init

{

return [self initWithProductName:@"Unknown"];

}

Notice that this new overridden init doesn’t do much work – it just calls the initWithProductName: method, which does the heavy lifting.

To test out your two initializers, you’ll need a description method. Implement description in Appliance.m:

- (NSString *)description

{

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

}

Now, in main.m, exercise the class a bit:

#import

#import "Appliance.h"

int main (int argc, const char * argv[])

{

@autoreleasepool {

Appliance *a = [[Appliance alloc] init];

NSLog(@"a is %@", a);

[a setProductName:@"Washing Machine"];

[a setVoltage:240];

NSLog(@"a is %@", a);

}

return 0;

}

Build and run the program.

Let’s take our exploration of initializers further. Create a new file: a subclass of Appliance named OwnedAppliance.

Figure 29.2 Creating a subclass of Appliance

In OwnedAppliance.h, add a mutable set of owner names and three methods.

#import "Appliance.h"

@interface OwnedAppliance : Appliance {

NSMutableSet *ownerNames;

}

- (id)initWithProductName:(NSString *)pn

firstOwnerName:(NSString *)n;

- (void)addOwnerNamesObject:(NSString *)n;

- (void)removeOwnerNamesObject:(NSString *)n;

@end

Notice that one of the methods you’ve declared is an initializer that takes two arguments.

Implement the methods in OwnedAppliance.m:

#import "OwnedAppliance.h"

@implementation OwnedAppliance

- (id)initWithProductName:(NSString *)pn

firstOwnerName:(NSString *)n

{

// Call the superclass's initializer

self = [super initWithProductName:pn];

if (self) {

// Make a set to hold owner names

ownerNames = [[NSMutableSet alloc] init];

// Is the first owner name non-nil?

if (n) {

[ownerNames addObject:n];

}

}

// Return a pointer to the new object

return self;

}

- (void)addOwnerNamesObject:(NSString *)n

{

[ownerNames addObject:n];

}

- (void)removeOwnerNamesObject:(NSString *)n

{

[ownerNames removeObject:n];

}

@end

Note that this class doesn’t initialize voltage or productName. The initWithProductName: in Appliance takes care of those. When you create a subclass, you typically only need to initialize the instance variables that you introduced; let the superclass take care of the instance variables that it introduced.

Now, however, you face the same situation as you did with Appliance and its superclass’s initializer, init. At the moment, one of your co-workers might create a terrible bug with this line of code:

OwnedAppliance *a = [[OwnedAppliance alloc] initWithProductName:@"Toaster"];

This code will cause the initWithProductName: method in Appliance to run. This method knows nothing about the ownerNames set, which means ownerNames will not get properly initialized for this OwnedAppliance instance.

The fix here is the same as before. In OwnedAppliance.m, add an implementation of the superclass’s initializer initWithProductName: that calls initWithProductName:firstOwnerName: and passes a default value for firstOwnerName.

- (id)initWithProductName:(NSString *)pn

{

return [self initWithProductName:pn firstOwnerName:nil];

}

Quiz time: Do you also need to implement init in OwnedAppliance? No. At this point, the following code will work fine:

OwnedAppliance *a = [[OwnedAppliance alloc] init];

Why? Because there is no implementation of init in OwnedAppliance, this line will trigger the init method implemented in Appliance, which calls [self initWithProductName:@"Unknown"].

Return Main Page Previous Page Next Page

®Online Book Reader