number
// from 0 to 2 inclusive.
NSInteger adjectiveIndex = rand() % [randomAdjectiveList count];
NSInteger nounIndex = rand() % [randomNounList count];
// Note that NSInteger is not an object, but a type definition
// for "unsigned long"
NSString *randomName = [NSString stringWithFormat:@"%@ %@",
[randomAdjectiveList objectAtIndex:adjectiveIndex],
[randomNounList objectAtIndex:nounIndex]];
int randomValue = rand() % 100;
NSString *randomSerialNumber = [NSString stringWithFormat:@"%c%c%c%c%c",
'0' + rand() % 10,
'A' + rand() % 26,
'0' + rand() % 10,
'A' + rand() % 26,
'0' + rand() % 10];
BNRItem *newItem =
[[self alloc] initWithItemName:randomName
valueInDollars:randomValue
serialNumber:randomSerialNumber];
return newItem;
}
This method creates two arrays using the method arrayWithObjects: . This method takes a list of objects terminated by nil . nil is not added to the array; it just indicates the end of the argument list.
Then randomItem creates a string from a random adjective and noun, a random integer value, and another string from random numbers and letters. It then creates an instance of BNRItem and sends it the designated initializer message with these randomly-created objects and int as parameters.
In this method, you also used stringWithFormat: , which is a class method of NSString . This message is sent directly to NSString , and the method returns an NSString instance with the passed-in parameters. In Objective-C, class methods that return an object of their type (like stringWithFormat: and randomItem ) are called convenience methods .
Notice the use of self in randomItem . Because randomItem is a class method, self refers to the BNRItem class itself instead of an instance. Class methods should use self in convenience methods instead of their class name so that a subclass can be sent the same message. In this case, if you create a subclass of BNRItem , you can send that subclass the message randomItem . Using self (instead of BNRItem ) will allocate an instance of the class that was sent the message and set the instance’s isa pointer to that class.
Testing your subclass
Open main.m . Delete the code that previously created and logged a single BNRItem . Then add BNRItem instances to the array and log them instead. Change your main function to look just like this:
#import
#import "BNRItem.h"
int main (int argc, const char * argv[])
{
@autoreleasepool {
NSMutableArray *items = [[NSMutableArray alloc] init];
BNRItem *p = [[BNRItem alloc] initWithItemName:@"Red Sofa"
valueInDollars:100
serialNumber:@"A1B2C"];
NSLog(@"%@", p);
for (int i = 0; i < 10; i++) {
BNRItem *p = [BNRItem randomItem];
[items addObject:p];
}
for (int i = 0; i < [items count]; i++) {
NSLog(@"%@", [items objectAtIndex:i]);
}
items = nil;
}
return 0;
}
Build and run your application and then check the output in the log navigator. All you did was replace what objects you added to the array, and the code runs perfectly fine with a different output ( Figure 2.15 ). Creating this class was a success.
Figure 2.15 Application
Reshonda Tate Billingsley