Gold Challenge: Help Find My Mistake


#1

My solution to the Gold Challenge looks pretty much like the others I’ve seen posted here. I’m getting the containers, and I successfully execute the method to add items, but when I turn around and ask for an item count, it always shows zero. What am I missing?

BNRContainer.h

[code]#import <Foundation/Foundation.h>
#import “BNRItem.h”

@interface BNRContainer : BNRItem
{
NSMutableArray *subitems;
}

  • (id)initWithItemArray:(NSMutableArray *)itemList
    containerName:(NSString *)container
    valueInDollars:(int) value;

  • (void)addItem:(BNRItem *)item;

  • (NSUInteger)getItemCount;

@end[/code]

BNRContainer.m

[code]#import “BNRContainer.h”

@implementation BNRContainer

  • (id)initWithItemArray:(NSMutableArray *)itemList
    containerName:(NSString *)container
    valueInDollars:(int) value
    {
    self = [super initWithItemName:container valueInDollars:value serialNumber:@""];
    if (self){
    for (BNRItem *item in itemList){
    [self addItem:item];
    }
    }
    //NSLog (@"%lu", [self getItemCount]);
    return self;
    }

  • (void)addItem:(BNRItem *)item
    {
    [subitems addObject:item];
    }

  • (int)valueInDollars
    {
    int val = 0;
    for (BNRItem *item in subitems){
    val += [item valueInDollars];
    }
    return val;
    }

  • (NSUInteger)getItemCount
    {
    return [subitems count];
    }

  • (NSString *)description
    {
    NSString *descriptionString =
    [[NSString alloc] initWithFormat:@"%@: Worth $%d, recorded on %@. Holds the following %ld items:\n",
    itemName,
    valueInDollars,
    dateCreated,
    [self getItemCount]];

    for (BNRItem *item in subitems){

      [descriptionString stringByAppendingString:[item description]];
      [descriptionString stringByAppendingString: @"\n"];
    

    }

    return descriptionString;

}

@end[/code]

and main.m

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

@autoreleasepool {
    
    // Create a mutable array object, store its address in items variable
    NSMutableArray *items = [[NSMutableArray alloc] init];
    NSMutableArray *items2 = [[NSMutableArray alloc] init];
    NSMutableArray *items3 = [[NSMutableArray alloc] init];

    for (int i = 0; i < 4; i++) {
        BNRItem *p = [BNRItem randomItem];
        [items addObject:p];
    }
           
    BNRContainer *c1 = [[BNRContainer alloc] initWithItemArray:items  containerName:@"Container 1" valueInDollars:1];
    
    for (int i = 0; i < 4; i++) {
        BNRItem *p = [BNRItem randomItem];
        [items2 addObject:p];
    }
    
    BNRContainer *c2 = [[BNRContainer alloc] initWithItemArray:items2  containerName:@"Container 2" valueInDollars:2];
    
    [items3 addObject:[BNRItem randomItem]];
    [items3 addObject:[BNRItem randomItem]];
    [items3 addObject:c1];
    [items3 addObject:c2];
    
    BNRContainer *c3 = [[BNRContainer alloc] initWithItemArray:items3 containerName:@"Container3" valueInDollars:45];
    NSLog (@"%@", [c3 description]);
    
    
    

    // Destroy the array pointed to by items
    items = nil;
    
}
return 0;

}
[/code]


#2

You could have discovered this by yourself by inserting an NSLog statement in the getItemCount method to print out the value of subitems.

- (void)addItem:(BNRItem *)item
{   
    NSLog (@"---> %s: subitems: %p", __PRETTY_FUNCTION__, subitems);
    [subitems addObject:item];
}

subitems object is nil. You need to create an array object and assign it to subitems before you can invoke methods on it.

- (void)addItem:(BNRItem *)item
{   
    // Create our array object lazily
    if (!subitems)
    {
         subitems = [NSMutableArray array];
    }
    [subitems addObject:item];
}

#3

Thanks ibex!


#4

Thank you very much, I got the same problem, now I understand the message can’t
sent to the instance variable which dosen’t exist( but what about the object in this
situation? same?) , so we have to make it is not nil,or initialize it.