Chapter 2 Gold challenge solution help


#1

Im very close to getting this solution, but I’ve run into a problem and have been trying to work it out, but after hours of trying I think it may be beyond my understanding.

In my solution, I create two containers, then add the second container as an item to the first container, and that seems to be where things go wrong.

My code is listed below.
Can anyone see whats wrong here?
Any help would be greatly appreciated.

main.m

#import <Foundation/Foundation.h>
#import "RogItem.h"
#import "RogContainer.h"

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

    @autoreleasepool {

        // Create a mutable array object, store its address in items varialbe
        NSMutableArray *items = [[NSMutableArray alloc] init];
        for (int i = 0; i < 10; i++) {
            RogItem *p = [RogItem randomItem];
            [items addObject:p];
        }
                        
        RogContainer *container1 = [[RogContainer alloc] initWithContainerContents:items 
                                                                            containerName:@"Roger's" 
                                                                        valueOfContainer:35];
        NSLog(@"\nthis is container 1\n%@", container1);
        
        [items removeAllObjects];
        
        // Make a second container
        for (int i = 0; i < 10; i++) {
            RogItem *p = [RogItem randomItem];
            [items addObject:p];
        }
                
        RogContainer *container2 = [[RogContainer alloc] initWithContainerContents:items 
                                                                     containerName:@"For sale" 
                                                                  valueOfContainer:35];
        NSLog(@"\nthis is container 2\n%@", container2);

        
        // Add the second container as an item to the contents of the first container
        [container1 addItemToContainer:container2];
        
        NSLog(@"\n\n%@", container1);
        
        // Destroy the array pointed to by items
        items = nil;
        
    }
    return 0;
}

RogContainer.h

#import "RogItem.h"

@interface RogContainer : RogItem
{
    NSMutableArray *containerContents;
    NSString *containerName;
    int valueOfContainer;
}

// Initializers
- (id)initWithContainerContents:(NSMutableArray *)contents 
                    containerName:(NSString *)name 
                 valueOfContainer:(int)value;

- (id)init;

// Instance Variables
- (void)setContainerContents:(NSMutableArray *)contents;
- (NSMutableArray *)containerContents;

- (void)setContainerName:(NSString *)name;
- (NSString *)containerName;

- (void)setValueOfContainer:(int)value;
- (int)valueOfContainer;

// Methods
- (void)addItemToContainer:(RogItem *)item;



@end

RogContainer.m

#import "RogContainer.h"

@implementation RogContainer

// Container Initializers
- (id)initWithContainerContents:(NSMutableArray *)contents 
                  containerName:(NSString *)name 
               valueOfContainer:(int)value
{
    
    self = [super init];
    
    if (self) {
        [self setContainerContents];
        [self setContainerName:name];
        [self setValueOfContainer:value];
    }
    return self;
}

- (id)init
{
    return [self initWithContainerContents:[[NSMutableArray alloc] init] 
                             containerName:@"Container" 
                          valueOfContainer:0];
}

// Instance Variables
- (void)setContainerContents:(NSMutableArray *)contents
{
    containerContents = contents;
}

- (NSMutableArray *)containerContents
{
    return containerContents;
}

- (void)setContainerName:(NSString *)name
{
    containerName = name;
}

- (NSString *)containerName
{
    return containerName;
}

- (void)setValueOfContainer:(int)i
{
    valueOfContainer = i;
}

- (int)valueOfContainer
{
    return valueOfContainer;
}

// Methods

- (void)addItemToContainer:(id)item
{
    [[self containerContents] addObject:item];
}

- (NSString *)description
{
    NSString *descriptionString =
    [[NSString alloc] initWithFormat:
     @"\n\nContainer:%@ with value of $%d\nTotal value is $%d\nContains items:\n %@",
        containerName,
        valueOfContainer,
        [self valueInDollars],
        containerContents];
    
    return descriptionString;
}

// Total value of container + contents
- (int)valueInDollars
{
    int totalValue = 0;
    for (int i = 0; i < [containerContents count]; i++) {
        totalValue += [[containerContents objectAtIndex:i] valueInDollars];
    }
    return totalValue + valueOfContainer;
}

@end

RogItem.h

#import <Foundation/Foundation.h>

@interface RogItem : NSObject
{
    NSString *itemName;
    NSString *serialNumber;
    int valueInDollars;
    NSDate *dateCreated;
}

+ (id)randomItem;

- (id)initWithItemName:(NSString *)name
        valueInDollars:(int)value
          serialNumber:(NSString *)sNumber;

- (id)initWithItemName:(NSString *)name
          serialNumber:(NSString *)sNumber;

- (void)setItemName:(NSString *)str;
- (NSString *)itemName;

- (void)setSerialNumber:(NSString *)str;
- (NSString *)serialNumber;

- (void)setValueInDollars:(int)i;
- (int)valueInDollars;

- (NSDate *)dateCreated;

@end

RogItem.m

#import "RogItem.h"

@implementation RogItem

+ (id)randomItem
{
    // Create an array of three adjectives
    NSArray *randomAdjectiveList = [NSArray arrayWithObjects:@"Fluffy",
                                                             @"Rusty",
                                                             @"Shiny", nil];
    // Create an array of three nouns
    NSArray *randomNounList = [NSArray arrayWithObjects:@"Bear",
                                                        @"Spork",
                                                        @"Mac", nil];
    
    // Get the index of a random adjective/noun from the lists
    // Note: The % operator, called the modulo operator, gives
    // the remainder. So adjectiveIndex is a random 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];

    RogItem *newItem = 
        [[self alloc] initWithItemName:randomName 
                         valueInDollars:randomValue 
                           serialNumber:randomSerialNumber];
    return newItem;
}

- (id)initWithItemName:(NSString *)name 
        valueInDollars:(int)value 
          serialNumber:(NSString *)sNumber
{
    // Call the superclass's designated initializer
    self = [super init];
    
    // Did the superclass's designated initializer succeed?
    if (self) {
        // Give the instance variables initial values
        [self setItemName:name];
        [self setValueInDollars:value];
        [self setSerialNumber:sNumber];
        dateCreated = [[NSDate alloc] init];
    }
    // Return the address of the newly initialized object
    return self;
}

- (id)initWithItemName:(NSString *)name 
          serialNumber:(NSString *)sNumber    
{
    return [self initWithItemName:name 
                   valueInDollars:0 
                     serialNumber:sNumber];
}

- (id)init
{
    return [self initWithItemName:@"Item" 
                   valueInDollars:0 
                     serialNumber:@""];
}

- (void)setItemName:(NSString *)str
{
    itemName = str;
}

- (NSString *)itemName
{
    return itemName;
}

- (void)setSerialNumber:(NSString *)str
{
    serialNumber = str;
}

- (NSString *)serialNumber
{
    return serialNumber;
}

- (void)setValueInDollars:(int)i
{
    valueInDollars = i;
}

- (int)valueInDollars
{
    return valueInDollars;
}

- (NSDate *)dateCreated
{
    return dateCreated;
}

- (NSString *)description
{
    NSString *descriptionString =
        [[NSString alloc] initWithFormat:@"%@ (%@): Worth $%d, recorded on %@",
                                        itemName,
                                        serialNumber,
                                        valueInDollars,
                                        dateCreated];
    return descriptionString;
}
@end

Any help is greatly appreciated


#2

Ok I think I resolved the problem. It looks like both containers had the same pointers to the same array of Items, when It was my intension to have two arrays.

So in my solution I created another array items2 (items1 is the first array). These changes all appear in my main.m file.

main.m

#import <Foundation/Foundation.h>
#import "RogItem.h"
#import "RogContainer.h"

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

    @autoreleasepool {

        // Create a mutable array object, store its address in items varialbe
        NSMutableArray *items1 = [[NSMutableArray alloc] init];
        for (int i = 0; i < 10; i++) {
            RogItem *p = [RogItem randomItem];
            [items1 addObject:p];
        }
                        
        RogContainer *container1 = [[RogContainer alloc] initWithContainerContents:items1 
                                                                            containerName:@"Roger's" 
                                                                        valueOfContainer:35];
        NSLog(@"\nthis is container 1\n%@", container1);
        
        
        // Make a second container
        NSMutableArray *items2 = [[NSMutableArray alloc] init];

        for (int i = 0; i < 10; i++) {
            RogItem *p = [RogItem randomItem];
            [items2 addObject:p];
        }
                
        RogContainer *container2 = [[RogContainer alloc] initWithContainerContents:items2 
                                                                     containerName:@"For sale" 
                                                                  valueOfContainer:35];
        NSLog(@"\nthis is container 2\n%@", container2);
        
        // Add the second container as an item to the contents of the first container
        [container1 addItemToContainer:container2];
        
        NSLog(@"\n\n%@", container1);
        
        // Destroy the arrays pointed to by items
        items1 = nil;
        items2 = nil;
        
    }
    return 0;
}

However now I have a new problem. For some reason “\n” new line character does not print out as a new line for items in container2, instead “\n” is printed out.

my output

[code]2012-11-21 20:38:51.731 RandomPossessions[2723:403]
this is container 1

Container:Roger’s with value of $35
Total value is $563
Contains items:
(
“Rusty Spork (8Q2U8): Worth $73, recorded on 2012-11-22 01:38:51 +0000”,
“Shiny Spork (5Y2V3): Worth $40, recorded on 2012-11-22 01:38:51 +0000”,
“Rusty Spork (2F9Z7): Worth $40, recorded on 2012-11-22 01:38:51 +0000”,
“Rusty Bear (8G5V6): Worth $99, recorded on 2012-11-22 01:38:51 +0000”,
“Shiny Spork (3P9B1): Worth $10, recorded on 2012-11-22 01:38:51 +0000”,
“Rusty Mac (6R5C1): Worth $93, recorded on 2012-11-22 01:38:51 +0000”,
“Fluffy Spork (3E4O0): Worth $1, recorded on 2012-11-22 01:38:51 +0000”,
“Fluffy Mac (3A6T4): Worth $30, recorded on 2012-11-22 01:38:51 +0000”,
“Shiny Spork (8S3I1): Worth $77, recorded on 2012-11-22 01:38:51 +0000”,
“Rusty Spork (4F6F9): Worth $65, recorded on 2012-11-22 01:38:51 +0000”
)
2012-11-21 20:38:51.734 RandomPossessions[2723:403]

Container:Roger’s with value of $35
Total value is $1166
Contains items:
(
“Rusty Spork (8Q2U8): Worth $73, recorded on 2012-11-22 01:38:51 +0000”,
“Shiny Spork (5Y2V3): Worth $40, recorded on 2012-11-22 01:38:51 +0000”,
“Rusty Spork (2F9Z7): Worth $40, recorded on 2012-11-22 01:38:51 +0000”,
“Rusty Bear (8G5V6): Worth $99, recorded on 2012-11-22 01:38:51 +0000”,
“Shiny Spork (3P9B1): Worth $10, recorded on 2012-11-22 01:38:51 +0000”,
“Rusty Mac (6R5C1): Worth $93, recorded on 2012-11-22 01:38:51 +0000”,
“Fluffy Spork (3E4O0): Worth $1, recorded on 2012-11-22 01:38:51 +0000”,
“Fluffy Mac (3A6T4): Worth $30, recorded on 2012-11-22 01:38:51 +0000”,
“Shiny Spork (8S3I1): Worth $77, recorded on 2012-11-22 01:38:51 +0000”,
“Rusty Spork (4F6F9): Worth $65, recorded on 2012-11-22 01:38:51 +0000”,
"\n\nContainer:For sale with value of $35\nTotal value is $603\nContains items:\n (\n “Fluffy Spork (1P5F4): Worth $29, recorded on 2012-11-22 01:38:51 +0000”,\n “Fluffy Bear (3R2Q6): Worth $88, recorded on 2012-11-22 01:38:51 +0000”,\n “Rusty Bear (4X7P8): Worth $38, recorded on 2012-11-22 01:38:51 +0000”,\n “Shiny Mac (7E4L1): Worth $77, recorded on 2012-11-22 01:38:51 +0000”,\n “Shiny Bear (8K9Y2): Worth $35, recorded on 2012-11-22 01:38:51 +0000”,\n “Fluffy Spork (8J8T0): Worth $94, recorded on 2012-11-22 01:38:51 +0000”,\n “Rusty Bear (5E2Z1): Worth $42, recorded on 2012-11-22 01:38:51 +0000”,\n “Fluffy Spork (1K1G7): Worth $71, recorded on 2012-11-22 01:38:51 +0000”,\n “Rusty Mac (9X6C8): Worth $40, recorded on 2012-11-22 01:38:51 +0000”,\n “Fluffy Bear (3H0R6): Worth $54, recorded on 2012-11-22 01:38:51 +0000”\n)"
)
[/code]

All comments are welcome


#3

I see that others are having the same issues with the “\n” not producing the desired new line.
Also it seems that ibex10 has come up with a solution, using categories, see the link below.

viewtopic.php?f=213&t=5305