Building and running but still getting blank table


#1

I have entered all of the code from the chapter and have no warnings or errors. The code builds fine and launches in the simulator without issue. However I’m only getting a blank table view (like after the first time you are asked to compile and run) instead of one populated with 5 random items.

I have tried cleaning and forcing a quit of the app in the simulator – no difference.
I have gone through each line of code several times to ensure it doesn’t deviate from the book.

Is there something that has changed in iOS 6 that the book doesn’t contain? I checked the errata and such but couldn’t find anything.

Is it possibly a simulator issue?

Thanks for any help you can provide!


#2

Some copy of your code into the post could be useful.


#3

Will paste in the code below.

Also, I can verify that the random BNRItems are getting created and added to sharedStore.

My code…

ItemsViewController.h

#import <Foundation/Foundation.h>

@interface ItemsViewController : UITableViewController

@end

ItemsViewController.m

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

@implementation ItemsViewController

- (id)init
{
    self = [super initWithStyle:UITableViewStyleGrouped];
    if (self) {
        for (int i = 0; i < 5; i++) {
            [[BNRItemStore sharedStore] createItem];
        }
    }
    
    return self;
}

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

- (NSInteger)tableView:(UITableView *)tableView
 numberofRowsInSection:(NSInteger)section
{
    return [[[BNRItemStore sharedStore] allItems] count];
}

- (UITableViewCell *)tableView:(UITableView *)tableView
         cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    
    // Check for a reusable cell first, use that if it exists
    UITableViewCell *cell =
        [tableView dequeueReusableCellWithIdentifier:@"UITableViewCell"];
    
    // If there is no reusable cell of this type, create a new one
    if (!cell) {
        cell = [[UITableViewCell alloc]
                    initWithStyle:UITableViewCellStyleDefault
                  reuseIdentifier:@"UITableViewCell"];
    }
    
    BNRItem *p = [[[BNRItemStore sharedStore] allItems] objectAtIndex:[indexPath row]];
    
    [[cell textLabel] setText:[p description]];
    
    return cell;
}

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    return 1;
}

@end

HomepwnerAppDelegate.m

#import "HomepwnerAppDelegate.h"
#import "ItemsViewController.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

BNRItemStore.h

#import <Foundation/Foundation.h>

@class BNRItem;

@interface BNRItemStore : NSObject
{
    NSMutableArray *allItems;
}

// Notice that this is a class method and prefixed with a + instead of a -
+ (BNRItemStore *)sharedStore;

- (NSArray *)allItems;
- (BNRItem *)createItem;

@end

BNRItemStore.m

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

@implementation BNRItemStore

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

+ (BNRItemStore *)sharedStore
{
    static BNRItemStore *sharedStore = nil;
    if (!sharedStore)
        sharedStore = [[super allocWithZone:nil] init];
    
    return sharedStore;
}

- (id)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;
}

@end

Thanks again!


#4

I’m going through this study book for the second time now, and I’m having exactly the same problem.
It worked the first time without any issues.

The screen remains just black. I’ve tried to print some NSLog messages in the following method,
but nothing, (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath

I don’t think we are having access to the method.


#5

I’m having the same problem


#6

I don´t find any issue in your code. Did you find the solution meanwhile?


#7

No, I haven’t had much time to look at it further since (and was hoping someone else would have had the problem and found a solution).

I am planning on going through the chapter again, starting from scratch and seeing if I have the same issue.

Since another person is having the same issue I’m not confident it is something I’m doing though.


#8

Your error is in ItemsViewController.m

You have:

- (NSInteger)tableView:(UITableView *)tableView numberofRowsInSection:(NSInteger)section {

Notice the “numberofRowsInSelection”? Should be numberOfRowsInSelection.

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {

Your code will compile either way but with what you have written, you aren’t overriding the real method so you’re never telling the UITableView how many rows to have.


#9

Ahhhh, such an oversight on my part! Of course the overridden method signatures should have been one of the first things I checked.

Thanks so much for your reply and especially for taking the time to look through my code. It is very much appreciated!