Silver challenge question


#1

Whenever I run my programming it is crashing with the following error “[__NSCFConstantString valueInDollars]: unrecognized selector sent to instance 0x6a30”, I have rechecked it, but couldn’t understand what my mistake is. Can anyone help me with this.

#import “BNRItemsViewController.h”
#import “BNRItem.h”
#import “BNRItemStore.h”

@implementation BNRItemsViewController

// Call the super class’s designated initilizer
-(instancetype)init
{
self = [super initWithStyle:UITableViewStyleGrouped];

if (self)
{
    // Add five random items to the random items
    for (int i=0; i<5; i++)
    {
        [[BNRItemStore sharedStore]createItem];
        
    }
}
return self;

}

-(instancetype)initWithStyle:(UITableViewStyle)style
{
return [self init];
}

-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 2;
}

-(NSInteger) tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
NSArray *items = [[BNRItemStore sharedStore]allItems];
NSMutableArray *itemsOver50 = [self itemsOver50:items];
NSMutableArray *itemsUnder50 = [self itemsUnder50:items];

if (section == 0)
{
    return [itemsUnder50 count]+1;
}
else
{
    return [itemsOver50  count]+1;
}

}

-(NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
if (section==0)
{
return @“Section under $50”;
}
else
return @“Section Over $50”;
}

// gets a mutable array of items that have a value over 50
-(NSMutableArray *)itemsOver50: (NSArray *)allItems
{
NSMutableArray *over50Items = [[NSMutableArray alloc] init];

for (BNRItem *item in allItems)
{
    if (item.valueInDollars >= 50)
    {
        [over50Items addObject:item];
    }
}

return over50Items;

}

// gets a mutable array of items that have a value over 50
-(NSMutableArray *)itemsUnder50: (NSArray *)allItems
{
NSMutableArray *itemsUnder50 = [[NSMutableArray alloc] init];

for (BNRItem *item in allItems)
{
    if (item.valueInDollars < 50)
    {
        [itemsUnder50 addObject:item];
    }
}

return itemsUnder50;

}

// Create and retrieve UITableViewCell
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
// Get a new or recycled cell
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@“UITableViewCell” forIndexPath:indexPath];

// Set the text on the cell with the description of the item that is at the nth index of the
// items, where n=row this cell will appearin on the tableView

NSArray *items = [[BNRItemStore sharedStore]allItems];
NSMutableArray *itemsOver50 = [self itemsOver50:items];
NSMutableArray *itemsUnder50 = [self itemsUnder50:items];

if (!cell)
{
    cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"UITableViewCell"];
}

if (indexPath.section==0)
{
    if ([indexPath row] < [tableView numberOfRowsInSection:indexPath.section]-1)
    {
        BNRItem *bItem = [itemsUnder50 objectAtIndex:[indexPath row]];
        [[cell textLabel] setText:[bItem description]];
        [cell setUserInteractionEnabled:YES];
    }
    else
    {
        [[cell textLabel] setText:@"No more items!"];
        [cell setUserInteractionEnabled:NO];
    }
}
  else
  {
      if ([indexPath row] < [tableView numberOfRowsInSection:indexPath.section]-1)
      {
          BNRItem *bItem = [itemsOver50 objectAtIndex:[indexPath row]];
          [[cell textLabel] setText:[bItem description]];
          [cell setUserInteractionEnabled:YES];
      }
      else
      {
          [[cell textLabel] setText:@"No more items!"];
          [cell setUserInteractionEnabled:NO];
      }

  }

return cell;
}

// Override ViewDidLoad to register UITableViewCell class with the table view
-(void)viewDidLoad
{
[super viewDidLoad];

self.tableView.contentInset = UIEdgeInsetsMake(20.0f, 0.0f, 0.0f, 0.0f);

[self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:@"UITableViewCell"];

}
@end


#2

I don’t think the error is in the code you’ve listed. The crash is telling you “Hey, you tried to ask an NSString what its valueInDollars is, and NSString doesn’t know what that means.” Without seeing the rest of the code, I think that NSString objects are getting added to the array of all items.

Could you show me your createItem method?


#3

[quote]This is the method I used.
[/quote]

-(BNRItem *)createItem { // Create an instance of BNRItem BNRItem *item = [BNRItem randomItem]; [self.privateItems addObject:item]; return item; }


#4

Can you also show us your randomItem method?


#5

I don’t think any mistake in randomItem method. But still here it is.[code]+(instancetype)randomItem
{
// Create immutable array of three adjectives
NSArray *randomAdjectiveList = @[@“Fluffy”,@“Rusty”,@“Shiny”];

// Create immutable array of three nouns
NSArray *randomNounList = @[@"Bear",@"Spork",@"Mac"];

// Get the index of random adjective/noun from the list
// N​o​t​e​:​ ​T​h​e​ ​%​ ​o​p​e​r​a​t​o​r​,​ ​c​a​l​l​e​d​ ​t​h​e​ ​m​o​d​u​l​o​ ​o​p​e​r​a​t​o​r​,​ ​g​i​v​e​s
 //​y​o​u​ ​t​h​e​ ​r​e​m​a​i​n​d​e​r​.​ ​S​o​ ​a​d​j​e​c​t​i​v​e​I​n​d​e​x​ ​i​s​ ​a​ ​r​a​n​d​o​m​ ​n​u​m​b​e​r
// from 0 to 2 inclusive
NSInteger adjectiveIndex = arc4random() % [randomAdjectiveList count];
NSInteger nounIndex = arc4random() % [randomNounList count];

NSString *randomName = [NSString stringWithFormat:@"%@ %@",randomAdjectiveList [adjectiveIndex],randomNounList [nounIndex]];

int randomValue = arc4random() % 100;

NSString *randomSerialNumber = [NSString stringWithFormat:@"%c%c%c%c%c",
                                'O' + arc4random() % 10,
                                'A' + arc4random() % 26,
                                'O' + arc4random() % 10,
                                'A' + arc4random() % 26,
                                'O' + arc4random() % 10];

BNRItem *newItem = [[BNRItem alloc]initWithItemName:randomName SerialNumber:randomSerialNumber andValueInDollars:randomValue];

return newItem;

}
[/code]


#6

Maybe I’m being stupid here but

Why does that say andValueInDollars: ? Shouldn’t that be valueInDollars instead? That is the method you send in the message in the BNRItemsViewController.
Try removing the and bit and see what happens?

To clarify, you would need to edit that in the init method that you call in this line as well.


#7

I think I figured it out, I believe this is a correct method. Just made some changes in createItem method as suggested. Thanks for the suggestions and help. It really helped me out.

-(BNRItem *)createItem
{
    NSMutableArray *itemOver50;
    NSMutableArray *itemUnder50;
    
    // Create an instance of BNRItem
    BNRItem *item = [BNRItem randomItem];
    [self.privateItems addObject:item];
    
    if (item.valueInDollars > 50)
    {
        [itemOver50 addObject:item];
    }
    else
    {
        [itemUnder50 addObject:item];
    }

    return item;
}