Silver Challenge: Solution and description Method Question


Hello all,

I stubbled across a strange reaction when I called the description method for the “No More Items” cell. I thought I would need to implement an if statement in tableView:cellForRowAtIndexPath: to have the “No More Items” cell display correctly. However, assigning the BNRItem pointer in tableView:cellForRowAtIndexPath: to an NSString object (in this case @“No More Items”) and then using BNRItem’s description method works.

My initial thought was that BNRItem and NSString have NSObject as a common ancestor, and this relationship allows the description method to correctly display the NSString object. But looking at BNRItem’s description method makes me think this loophole has more to do with the implementation of the description method. Thoughts anyone?

I’ve only modified ItemViewController class in my application. All other source code is the same as in the book.

---- Source Code ----


[code]#import <Foundation/Foundation.h>

@interface ItemsViewController : UITableViewController

@property (strong, nonatomic) NSMutableArray *cheapItems, *expensiveItems;
@property (strong, nonatomic) NSArray *titlesForSectionHeaders;
@property (strong, nonatomic) NSArray *sectionIndices;



[code]#import “ItemsViewController.h”
#import “BNRItemStore.h”
#import “BNRItem.h”

@implementation ItemsViewController

// Call the superclass’s designated initializer
self = [super initWithStyle:UITableViewStyleGrouped];
if (self) {
for (int i = 0; i < 50; i++) {
[[BNRItemStore sharedStore] createItem];

    self.cheapItems = [NSMutableArray array];
    self.expensiveItems = [NSMutableArray array];
    for (BNRItem *item in [[BNRItemStore sharedStore] allItems]) {
        if (item.valueInDollars > 50)
            [self.expensiveItems addObject:item];
            [self.cheapItems addObject:item];
    self.sectionIndices = [NSArray arrayWithObjects:self.expensiveItems,
                           self.cheapItems, nil];
    self.titlesForSectionHeaders = [NSArray arrayWithObjects:@"Expensive Items", @"Cheap Items", nil];
return self;


return [self init];

-(NSInteger)tableView:(UITableView *)tableView
if (section == [self.sectionIndices count] - 1) {
[self.sectionIndices[section] addObject:@“No More Items!”];

NSLog(@"Section count: %d", [self.sectionIndices count]);
NSLog(@"Section: %d Rows: %d", section, [self.sectionIndices[section] count]);

return [self.sectionIndices[section] count];


-(UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath
UITableViewCell *cell =
[tableView dequeueReusableCellWithIdentifier:@“UITableViewCell”];

if (!cell) {
    cell = [[UITableViewCell alloc]

NSLog(@"IndexPath Section: %d, Row: %d",
      indexPath.section, indexPath.row);

BNRItem *p = [[self.sectionIndices objectAtIndex:indexPath.section]

// Causes crash when "No More Items" cell is displayed

// NSLog(@“BNRItem: %@”, p.itemName);

// Does not cause crash

// NSLog(@“BNRItem: %@”, p);

// description method inherited from common ancestor (NSObject)
// allows the proper description of "No More Items!" NSString ???
[[cell textLabel] setText:[p description]];

return cell;


-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
return [self.titlesForSectionHeaders count];

-(NSString *)tableView:(UITableView *)tableView
return self.titlesForSectionHeaders[section];