Wrong numbers of rows, and other strange things

#1

Hi there,

So I have three issues or wonders.

[ul][size=150]1. Numbers of Rows[/size][/ul]
First, I don’t get the same table as the one in the book: I have more rows than what we should expect. Let me use the code I have in my Bronze Challenge (which is the same as the one from the chapter).
We explicitly tell the compiler the numbers or rows in each section in this line of code:

-(NSInteger)tableView:(UITableView *)tableView
numberOfRowsInSection:(NSInteger)section
{
    if (section == 0) {
        return [[[BNRItemStore sharedStore] allItemsInf50] count];
    } else  {
        return [[[BNRItemStore sharedStore] allItemsSup50] count];
    }
}

But still, if I input 11 items or less, I have many more rows than 11, and if I put 12 items or more, I have exactly the correct number of rows. Why ?? I looked for a few hours why and I couldn’t figure out…

[ul][size=150]2. Number of sections[/size][/ul]
Then another strange stuff with this code:

-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    NSLog(@"This tableview has %lu sections", [[[BNRItemStore sharedStore] allItems] count]);
    return [[[BNRItemStore sharedStore] allItems] count];
}

The sentence always appears 6 times in the log, whatever number of items I choose. I tried to figure out why with the debugger help, but still it’s a failure…

[ul][size=150]3. Which one is the appropriate method ?[/size][/ul]

We have two options for the Bronze Challenge: either we separate the items > and < 50 $ in BNRItemStore, and then adapt the BNRItemViewController to have two sections, one for each category. Either we don’t touch BNRItemStore and we modify BNRItemsViewController only.

I would say that, in the MVC diagram, the separation of the items belong to the Model (dealing with the data), but I am not sure anymore as the UITableViewController also handle the datasource… I am confused, what is the best if we want to follow the conventions properly ?

Here is all my code for anyone who could help me on this !

BNRItemStore.h

#import <Foundation/Foundation.h>

@class BNRItem;

@interface BNRItemStore : NSObject

@property (nonatomic, readonly) NSArray *allItemsInf50;
@property (nonatomic, readonly) NSArray *allItemsSup50;
@property (nonatomic, readonly) NSArray *allItems;

+(instancetype)sharedStore;
-(BNRItem *)createItem;

@end

BNRItemStore.m


#import "BNRItemStore.h"
#import "BNRItem.h"

@interface BNRItemStore ()

@property (nonatomic) NSMutableArray *privateItemsInf50;
@property (nonatomic) NSMutableArray *privateItemsSup50;

@end

@implementation BNRItemStore

+(instancetype)sharedStore
{
    static BNRItemStore *sharedStore = nil;
    if (!sharedStore) {
        sharedStore = [[self alloc] initPrivate];
    }
    return sharedStore;
}

-(instancetype)init
{
    @throw [NSException exceptionWithName:@"Singleton"
                                   reason:@"Use +[BNRItemStore sharedStore]"
                                 userInfo:nil];
    return nil;
}

-(instancetype)initPrivate
{
    self = [super init];
    if (self) {
        _privateItemsInf50 = [[NSMutableArray alloc] init];
        _privateItemsSup50 = [[NSMutableArray alloc] init];
    }
    return self;
}

-(NSArray *)allItemsInf50
{
    return self.privateItemsInf50;
}

-(NSArray *)allItemsSup50
{
    return self.privateItemsSup50;
}

-(NSArray *)allItems
{
    NSArray *allItems = [[NSArray alloc] initWithObjects:_privateItemsInf50, _privateItemsSup50, nil];
    return allItems;
}

-(BNRItem *)createItem
{
    BNRItem *item = [BNRItem randomItem];
    
    if (item.valueInDollars <= 50) {
        [self.privateItemsInf50 addObject:item];
    } else {
        [self.privateItemsSup50 addObject:item];
    }
    return item;
}

@end

BNRItemsViewController.m

#import "BNRItemsViewController.h"
#import "BNRItemStore.h"
#import "BNRItem.h"

@interface BNRItemsViewController()

@end


@implementation BNRItemsViewController


//Designated Initializer is initWithStyle  Changing to init
-(instancetype)init
{
    //ALWAYS call the superclass's designated initializer
    self = [super initWithStyle:UITableViewStylePlain];
    
    self.tableView.separatorColor = [UIColor blueColor];
    
    if (self) {
        for (int i = 0; i < 11; i++) {
            [[BNRItemStore sharedStore] createItem];
            }
        }
    return self;
    
}

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

-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    NSLog(@"This tableview has %lu sections", [[[BNRItemStore sharedStore] allItems] count]);
    return [[[BNRItemStore sharedStore] allItems] count];
}


-(NSInteger)tableView:(UITableView *)tableView   numberOfRowsInSection:(NSInteger)section
{
    if (section == 0) {
        return [[[BNRItemStore sharedStore] allItemsInf50] count];
    } else  {
        return [[[BNRItemStore sharedStore] allItemsSup50] count];
    }
}

-(NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
    if (section == 0) {
        return @"Items < $50";
    } else {
       return @"Items > $50";
    }
}


-(UITableViewCell *)tableView:(UITableView *)tableView    cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    //Get a new or recycled cell
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"UITableViewCell"
                                                            forIndexPath:indexPath];
        
    NSArray *items = [[NSArray alloc] init];
    BNRItem *item = [[BNRItem alloc] init];
    
    if ([indexPath section] == 0) {
        items = [[BNRItemStore sharedStore] allItemsInf50];
        item = items[indexPath.row];
    } else if ([indexPath section] == 1){
        items = [[BNRItemStore sharedStore] allItemsSup50];
        item = items[indexPath.row];
    }
    
    cell.textLabel.text = [item description];
    
    return cell;
}

-(void)viewDidLoad
{
    [super viewDidLoad];
    self.tableView.contentInset = UIEdgeInsetsMake(20.0f, 0.0f, 0.0f, 0.0f);

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

@end

Thanks everyone !