Question on Silver challenge


#1

I don’t quite understand why I’m getting an error with this challenge. I used the Predicate approach that others have used for the Bronze challenge and that worked great. I’m trying to add a “No more items!” cell to the bottom of the 2nd section I created in the Bronze challenge.

ItemsViewController.m

[code]- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
NSPredicate *predicate;
if (section == 0) {
predicate = [NSPredicate predicateWithFormat:@“valueInDollars > 50”];
} else {
predicate = [NSPredicate predicateWithFormat:@“valueInDollars <= 50”];
}

NSArray *filteredArray = [[[BNRItemStore sharedStore] allItems] filteredArrayUsingPredicate:predicate];

NSInteger numRows = [filteredArray count];

if (section == 0) {
return numRows;
} else {
return numRows + 1;
}
}

  • (UITableViewCell *)tableView:(UITableView *)tableView
    cellForRowAtIndexPath:(NSIndexPath *)indexPath
    {
    //Check for a reusable cell first, and use it if it exists
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@“UITableViewCell”];

    //If there is no cell of this type create a new one
    if (!cell) {
    cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
    reuseIdentifier:@“UITableViewCell”];
    }

    //Bronze challenge - use predicate to filter array based on dollar value
    NSPredicate *predicate;
    if ([indexPath section] == 0) {
    predicate = [NSPredicate predicateWithFormat:@“valueInDollars > 50”];
    } else {
    predicate = [NSPredicate predicateWithFormat:@“valueInDollars <= 50”];
    }

    //Create a filtered array based on the predicate
    NSArray *filteredArray = [[[BNRItemStore sharedStore] allItems] filteredArrayUsingPredicate:predicate];

    //Set the row text based on the item’s description
    //Silver challenge

    if ([indexPath section] == 0) {
    BNRItem *item = [filteredArray objectAtIndex:[indexPath row]];
    [[cell textLabel] setText:[item description]];
    } else {

      if ([indexPath row] <= [filteredArray count]) {  
          BNRItem *item = [filteredArray objectAtIndex:[indexPath row]]; //This is where I'm getting the error
          [[cell textLabel] setText:[item description]];
      } else {
          [[cell textLabel] setText:@"No more items!"];
      }
    

    }

    return cell;
    }[/code]

And here is the error:
2012-10-20 18:10:48.363 Homepwner[90332:f803] *** Terminating app due to uncaught exception ‘NSRangeException’, reason: ‘*** -[__NSArrayI objectAtIndex:]: index 3 beyond bounds [0 … 2]’
*** First throw call stack:
(0x13ca022 0x155bcd6 0x13b6644 0x2b71 0xaec54 0xaf3ce 0x9acbd 0xa96f1 0x52d21 0x13cbe42 0x1d82679 0x1d8c579 0x1d114f7 0x1d133f6 0x1da0160 0x12e84 0x13767 0x22183 0x22c38 0x16634 0x12b4ef5 0x139e195 0x1302ff2 0x13018da 0x1300d84 0x1300c9b 0x12c65 0x14626 0x1fad 0x1f15 0x1)
terminate called throwing an exception(lldb)


#2

Let’s say filteredArray had only one entry in it and indexPath.row equalled 1, then you would be trying to access past beyond the contents of filteredArray; this would cause a crash. You are probably experiencing a smilar scenario.


#3

Ah you are right, simply changing [indexPath row] <= [filteredArray count] to [indexPath row] < [filteredArray count] fixes the issue. Thanks!


#4

thanks a lot for posting this question I didn’t know about this class.


#5

I’ve been getting this error even with the change suggested. I’ve tried substituting @ballred’s code line for line and am still getting it. Any ideas?


#6

Post all your headers and main files and I can take a quick look.


#7

Try this: