BNRItems not displaying


#1

The typed the code after studying it from the book. It is exactly the same. I found no typos in method names. Still the simulator shows a Blank UITableView. I just couldn’t figure out whats happening. I’m running it in iOS 6 environment.
Here’s the code…
HomePwnerAppDelegate.h

//
//  HomePwnerAppDelegate.h
//  HomePwner
//
//  Created by Rahul Agarwal on 13/10/13.
//  Copyright (c) 2013 Rahul Agarwal. All rights reserved.
//

#import <UIKit/UIKit.h>
#import "ItemsViewController.h"
@interface HomePwnerAppDelegate : UIResponder <UIApplicationDelegate>

@property (strong, nonatomic) UIWindow *window;

@end

HomePwnerAppDelegate.m

//
//  HomePwnerAppDelegate.m
//  HomePwner
//
//  Created by Rahul Agarwal on 13/10/13.
//  Copyright (c) 2013 Rahul Agarwal. All rights reserved.
//

#import "HomePwnerAppDelegate.h"

@implementation HomePwnerAppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    // Override point for customization after application launch.
    ItemsViewController *itemsViewController= [[ItemsViewController alloc] init];
    
    [self.window setRootViewController:itemsViewController];
    self.window.backgroundColor = [UIColor whiteColor];
    [self.window makeKeyAndVisible];
    return YES;
}

- (void)applicationWillResignActive:(UIApplication *)application
{
    // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
    // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
}

- (void)applicationDidEnterBackground:(UIApplication *)application
{
    // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 
    // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
}

- (void)applicationWillEnterForeground:(UIApplication *)application
{
    // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
}

- (void)applicationDidBecomeActive:(UIApplication *)application
{
    // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
}

- (void)applicationWillTerminate:(UIApplication *)application
{
    // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
}

@end

ItemsViewController.h

//
//  ItemsViewController.h
//  HomePwner
//
//  Created by Rahul Agarwal on 13/10/13.
//  Copyright (c) 2013 Rahul Agarwal. All rights reserved.
//

#import <UIKit/UIKit.h>
#import "BNRItem.h"
#import "BNRItemStore.h"
@interface ItemsViewController : UITableViewController <UITableViewDataSource, UITableViewDelegate>

@end

ItemsViewController.m

//
//  ItemsViewController.m
//  HomePwner
//
//  Created by Rahul Agarwal on 13/10/13.
//  Copyright (c) 2013 Rahul Agarwal. All rights reserved.
//

#import "ItemsViewController.h"

@interface ItemsViewController ()

@end

@implementation ItemsViewController

-(id) init{
    
    self= [super initWithStyle:UITableViewStyleGrouped];
    if (self) {
        
//    NSLog(@"%@ %@ %@", [(UITableView *)self.view dataSource],[(UITableView *)self.view delegate], self);
        for (int i=0; i<5; i++) {
            [[BNRItemStore sharedStore] createItem];
        }
        
//        NSLog(@"Protocol conformance- %d",[self conformsToProtocol:@protocol(UITableViewDelegate)]);
//        NSIndexPath *indexPath= [[NSIndexPath alloc] init];
//        [self numberOfSectionsInTableView:(UITableView *)self.view];
//        [self tableView:(UITableView *)self.view numberOfRowsInSection:5];
//        [self tableView:(UITableView *)self.view cellForRowAtIndexPath:indexPath];
    }
    return self;
}
- (id)initWithStyle:(UITableViewStyle)style
{
    return [self init];
    
}

- (void)viewDidLoad
{
    [super viewDidLoad];
    
    // Uncomment the following line to preserve selection between presentations.
    // self.clearsSelectionOnViewWillAppear = NO;
    
    // Uncomment the following line to display an Edit button in the navigation bar for this view controller.
    // self.navigationItem.rightBarButtonItem = self.editButtonItem;
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

#pragma mark - Table view data source

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
//    NSLog(@"%d",[tableView numberOfSections]);
    return 0;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
//#warning Incomplete method implementation.
    // Return the number of rows in the section.
    NSLog(@"No. of sections- %d",section);
    return [[[BNRItemStore sharedStore] allItems] count] ;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSLog(@"hello");
    static NSString *CellIdentifier = @"Cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
    
    // Configure the cell...
    if (!cell) {
        cell= [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
    }
    
    BNRItem *p= [[[BNRItemStore sharedStore] allItems] objectAtIndex:[indexPath row]];
    [[cell textLabel] setText:[p description]];
    
    return cell;
}

/*
 // Override to support conditional editing of the table view.
 - (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
 {
 // Return NO if you do not want the specified item to be editable.
 return YES;
 }
 */

/*
 // Override to support editing the table view.
 - (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
 {
 if (editingStyle == UITableViewCellEditingStyleDelete) {
 // Delete the row from the data source
 [tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];
 }
 else if (editingStyle == UITableViewCellEditingStyleInsert) {
 // Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
 }
 }
 */

/*
 // Override to support rearranging the table view.
 - (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath
 {
 }
 */

/*
 // Override to support conditional rearranging of the table view.
 - (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath
 {
 // Return NO if you do not want the item to be re-orderable.
 return YES;
 }
 */

/*
 #pragma mark - Navigation
 
 // In a story board-based application, you will often want to do a little preparation before navigation
 - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
 {
 // Get the new view controller using [segue destinationViewController].
 // Pass the selected object to the new view controller.
 }
 
 */

@end

BNRItemStore.h

[code]//
// BNRItemStore.h
// HomePwner
//
// Created by Rahul Agarwal on 13/10/13.
// Copyright © 2013 Rahul Agarwal. All rights reserved.
//

#import <Foundation/Foundation.h>
@class BNRItem;
@interface BNRItemStore : NSObject{
NSMutableArray *allItems;
}
+(BNRItemStore *)sharedStore;
-(NSArray *)allItems;
-(BNRItem *)createItem;

@end
[/code]

BNRItemStore.m

[code]//
// BNRItemStore.m
// HomePwner
//
// Created by Rahul Agarwal on 13/10/13.
// Copyright © 2013 Rahul Agarwal. All rights reserved.
//

#import “BNRItemStore.h”
#import “BNRItem.h”
@implementation BNRItemStore
-(id)init{
NSLog(@“BNRItemStore’s init!”);
self= [super init];
if (self) {
allItems= [[NSMutableArray alloc] init];
}
return self;
}
-(NSArray *)allItems{
return allItems;
}
-(BNRItem *)createItem{
BNRItem *p= [BNRItem randomItem];
[allItems addObject:p];
return p;
}
+(BNRItemStore *)sharedStore{
static BNRItemStore *sharedStore=nil;
if (!sharedStore)
sharedStore= [[super allocWithZone:nil] init];

NSLog(@"%@",sharedStore);
return sharedStore;

}
+(id)allocWithZone:(NSZone *)zone{
return [self sharedStore];
}

@end
[/code]

BNRItem.h

//
//  BNRItem.h
//  BNRItem
//
//  Created by Rahul Agarwal on 10/06/13.
//  Copyright (c) 2013 Rahul Agarwal. All rights reserved.
//

#import <Foundation/Foundation.h>

@interface BNRItem : NSObject
{
    NSString *itemName;
    int valueInDollars;
    NSString *serialNumber;
    NSDate *dateCreated;
    
    //Used for Retain cycle 
    __weak BNRItem *container;
    BNRItem *containedItem;
}
+(id)randomItem;
-(void)setItemName:(NSString *)name;
-(NSString *)itemName;

-(void)setSerialNumber:(NSString *)serialNumber;
-(NSString *)serialNumber;

-(void)setValueInDollars:(int)valueInDollars;
-(int)valueInDollars;

-(id)initWithItemName:(NSString *)name valueInDollars:(int)valueInDollars serialNumber:(NSString *)serialName;
-(id)initWithItemName:(NSString *)name;
-(id)initWithItemName:(NSString *)name serialNumber:(NSString *)serialName;

//Used for Retain cycle
-(void)setContainedItem:(BNRItem *)item;
-(BNRItem *)containedItem;
-(void)setContainer:(BNRItem *)item;
-(BNRItem *)container;
@end

BNRItem.m

//
//  BNRItem.m
//  BNRItem
//
//  Created by Rahul Agarwal on 10/06/13.
//  Copyright (c) 2013 Rahul Agarwal. All rights reserved.
//

#import "BNRItem.h"

@implementation BNRItem
+(id)randomItem{
    //Item Names
    NSArray *nounList= [NSArray arrayWithObjects:@"Mac",@"iPhone",@"iPad", nil];
    NSArray *adjectiveList=[NSArray arrayWithObjects:@"Snazzy",@"Cool",@"Sexy", nil];
    
    int randomNounIndex= rand()%[nounList count];
    int randomAdjectiveIndex=rand()% [adjectiveList count];
    
    NSString *randomName=[NSString stringWithFormat:@"%@ %@",[adjectiveList objectAtIndex:randomAdjectiveIndex],[nounList objectAtIndex:randomNounIndex]];
    
    //Item ValuesInDollars
    int randomValue=rand()%100;
    
    //Item Serial-Numbers
    NSString *randomSerialNumber=[NSString stringWithFormat:@"%c%c%c%c%c",'A'+rand()%26,'0'+rand()%10,'0'+rand()%10,'A'+rand()%26,'A'+rand()%26];
    
    BNRItem *newItem=[[self alloc] initWithItemName:randomName valueInDollars:randomValue serialNumber:randomSerialNumber];
    return newItem;
}
-(void)setItemName:(NSString *)currentItemName{
    itemName=currentItemName;
}
-(NSString *)itemName{
    return itemName;
}
-(void)setSerialNumber:(NSString *)currentSerialNumber{
    serialNumber=currentSerialNumber;
}
-(NSString *)serialNumber{
    return serialNumber;
}
-(void)setValueInDollars:(int)currentValueInDollars{
    valueInDollars=currentValueInDollars;
}
-(int)valueInDollars{
    return valueInDollars;
}
-(NSString *)description{
    return [NSString stringWithFormat:@"%@(%@) having %d dollars as cost.Date of listing: %@",[self itemName],[self serialNumber],[self valueInDollars],dateCreated];
}
-(id)init{
    return [self initWithItemName:@"Item" valueInDollars:0 serialNumber:@" "];
}
-(id)initWithItemName:(NSString *)name{
    return [self initWithItemName:name valueInDollars:0 serialNumber:@" "];
}
-(id)initWithItemName:(NSString *)name serialNumber:(NSString *)currentSerialName{
    return [self initWithItemName:name valueInDollars:0 serialNumber:currentSerialName];
}
-(id)initWithItemName:(NSString *)name valueInDollars:(int)currentValueInDollars serialNumber:(NSString *)currentSerialNumber{
    if (self=[super init]) {
        [self setItemName:name];
        [self setSerialNumber:currentSerialNumber];
        [self setValueInDollars:currentValueInDollars];
        dateCreated=[[NSDate alloc] init];
    }
    return self;
}
-(void)setContainedItem:(BNRItem *)item{
    containedItem=item;
    [item setContainer:self];
}
-(BNRItem *)containedItem{
    return containedItem;
}
-(void)setContainer:(BNRItem *)item{
    container=item;
}
-(BNRItem *)container{
    return container;
}
-(void)dealloc{
    NSLog(@"Destroyed object: %@",self);
}

@end

#2

[quote][code]
@implementation ItemsViewController

  • (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
    {
    // NSLog(@"%d",[tableView numberOfSections]);
    return 0;
    }

    [/code][/quote]
    Why is the above method returning zero?

#3

[quote=“ibex10”][quote][code]
@implementation ItemsViewController

  • (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
    {
    // NSLog(@"%d",[tableView numberOfSections]);
    return 0;
    }

    [/code][/quote]
    Why is the above method returning zero?[/quote]

I don’t remember what it originally was… I know that i had changed it to return [tableView numberOfSections] initially. But there was no change in the output. It still showed Blank TableView. Then when i changed it to return 1, it caused runtime error- *** Assertion failure in -[UITableView dequeueReusableCellWithIdentifier:forIndexPath:], /SourceCache/UIKit_Sim/UIKit-2380.17/UITableView.m:4460
2013-10-23 20:11:00.023 HomePwner[470:c07] *** Terminating app due to uncaught exception ‘NSInternalInconsistencyException’, reason: ‘unable to dequeue a cell with identifier Cell - must register a nib or a class for the identifier or connect a prototype cell in a storyboard’

I googled this and came across an article saying that in such cases one should use dequeueReusableCellWithIdentifier: instead of dequeueReusableCellWithIdentifier:forIndexPath:. Didn’t actually fully understand the reason.

I changed the code to-

[code]- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// NSLog(@"%d",[tableView numberOfSections]);
return 1;
}

  • (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
    {
    NSLog(@“hello”);
    static NSString *CellIdentifier = @“Cell”;
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];//NO INDEX PATH

    // Configure the cell…
    if (!cell) {
    cell= [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
    }

    BNRItem *p= [[[BNRItemStore sharedStore] allItems] objectAtIndex:[indexPath row]];
    [[cell textLabel] setText:[p description]];

    return cell;
    }
    [/code]