Silver Challenge: Solution and description Method Question


#1

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 ----

ItemViewController.h:

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

@interface ItemsViewController : UITableViewController

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

@end[/code]

ItemViewController.m:

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

@implementation ItemsViewController

-(instancetype)init
{
// 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];
        else
            [self.cheapItems addObject:item];
    }
    
    self.sectionIndices = [NSArray arrayWithObjects:self.expensiveItems,
                           self.cheapItems, nil];
    
    self.titlesForSectionHeaders = [NSArray arrayWithObjects:@"Expensive Items", @"Cheap Items", nil];
    
    
    
}
return self;

}

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

-(NSInteger)tableView:(UITableView *)tableView
numberOfRowsInSection:(NSInteger)section
{
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]
            initWithStyle:UITableViewCellStyleDefault
            reuseIdentifier:@"UITableViewCell"];
}

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

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

// 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
titleForHeaderInSection:(NSInteger)section
{
return self.titlesForSectionHeaders[section];
}

@end[/code]