Jake
Jake

Reputation: 1295

UITableView numberOfRowsInSection Will Not Load More than One Row

So I have a UITableView which should loop through a single NSMutableArray and use each of them as row labels. Currently the only way I can get this to run is with 0 or 1 rows, 2 or higher throws out an error saying the array index is off. I tried NSLog to output my array and can confirm it's reading all the Strings.

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

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    return 2;
} 

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {

}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    static NSString *CellIdentifier = @"Cell";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
    cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
    cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
}

// Set up the cell...
NSString *cellValue = [harvestRecipeList objectAtIndex:indexPath.row];
cell.textLabel.text = cellValue;

return cell;
} 

The array code is stored in the exact same file (MasterViewController.m) which I added below.

- (void)viewDidLoad
{
    [super viewDidLoad];

    harvestRecipeList = [[NSMutableArray alloc] init];

    [harvestRecipeList addObject:@"Ice Cream"];
    [harvestRecipeList addObject:@"Walnut Cake"];
    [harvestRecipeList addObject:@"Cookies"];
    [harvestRecipeList addObject:@"Salad"];
    [harvestRecipeList addObject:@"Grilled Fish"];

    //Set the title
    self.navigationItem.title = @"BTN Recipes";
}

I would love any help on this it's been bugging me. I was using [harvestRecipeList count] but this throws the same array index error. And as I mentioned I can get the app to run perfectly fine with 0 or 1 rows - thanks in advance for any help!

EDIT: here is the error I'm getting in the output window after building:

Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[__NSArrayI objectAtIndex:]: index 1 beyond bounds [0 .. 0]'

EDIT2: included below my property setup for harvestRecipeList

//MasterViewController.h
@interface MasterViewController : UITableViewController {
    NSMutableArray *harvestRecipeList;
}
@property (nonatomic, retain) NSMutableArray *harvestRecipeList;

// and also my MasterViewController.m 
@synthesize harvestRecipeList;

EDIT3 here's my source code zipped for this project. It's called treehouse, just a testing name for now but you can dl from my cloudapp here.

Upvotes: 2

Views: 3594

Answers (4)

Robotic Cat
Robotic Cat

Reputation: 5891

Updated Solution:

So I have checked your code and found the problem. Do the following:

  1. Go into your storyboard and select the Master Table View (click where it says Static Content)
  2. Click on the Attributes Inspector (looks like a downward arrow sort of) and change the content from Static Cells to Dynamic Prototypes
  3. Click on the prototype cell and type Cell into Identifier field (this is what you are using as a cell ID
  4. Also change the Accessory from None to Disclosure Indicator
  5. In your tableView:numberOfRowsInSection return self.harvestRecipeList.count
  6. In tableView:cellForRowAtIndexPath: you can remove the following two lines (as they are provided by the Storyboard):

    cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier]; cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;

  7. Recreate your Push segue from your Master Cell to your Detail View Controller

It should all now work fine - and I've tested that it works. The basic problem was you had specified Static Cells rather than Dynamic Prototypes and the rest of the instructions are just mopping up. The NSRangeException was caused by only having a single cell so that was all that was displayed.

Hope this helps.

Previous Solution:

So, a few comments but, first, if you've updated your code can you post an update?

  1. Your harvestRecipeList that you add objects to in ViewDidLoad does not appear to be the same harvestRecipeList that you synthesised - it will be local to the method so your instance variable will always be nil. You should always use self.harvestRecipeList - do this everywhere. This could easily explain your NSRangeException. Also see #4 below.
  2. In your tableView:numberOfRowsInSection: you should return self.harvestRecipeList.count
  3. If you are using the iOS5 SDK, you do not need to check if cell == nil as dequeueReusableCellWithIdentifier: is guaranteed to return non-nil cell. You do need to check if you are on the iOS4 SDK.
  4. Change your @synthesize harvestRecipeList; to @synthesize harvestRecipeList = _harvestRecipeList; as this will assist with #1 and checking you are accessing the ivar.

Try #1 & #2 as a minimum and then post an update on the problems you are having. Hope this helps.

Upvotes: 5

v1Axvw
v1Axvw

Reputation: 3054

I examined the code you put in the ZIP file. I immediately noticed your using the iOS 5 Storyboard feature. I haven't got Xcode 4 nor the iOS 5 SDK, so I could not test that part of your application.

However, I went on and coded your Storyboard part by hand. I have tested your MasterViewController solely and found no errors. I added in the AppDelegate this method to replace the Storyboard automatical features and just show the view controller where you think the error is coming from.

- (BOOL)application:(UIApplication *)application 
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    MasterViewController *myVC;
    _window = [[UIWindow alloc] initWithFrame:
               [[UIScreen mainScreen] applicationFrame]];
    myVC = [[MasterViewController alloc] initWithStyle:UITableViewStylePlain];
    [_window setAutoresizesSubviews:YES];
    [_window addSubview:myVC.view];

    [_window makeKeyAndVisible];
    return YES;
}

To prove your MasterViewController.m contains no error, I add this screenshot:

enter image description here

Conclusion: Your error is to be found somewhere else, probably in your Storyboard file. However I have never used that new functionality so I cannot help you with that. I suggest you review your Storyboard and put all attention to that file.

Upvotes: 2

v1Axvw
v1Axvw

Reputation: 3054

Okay, if your log messages display an array with five objects right before you try to query the second, and you application gives you an NSRangeException the bug is definitely not to be found in the code you show us.

Try to find it by placing various logs before and after any -[NSArray objectAtIndex:] and see which log doesn't come through after the call. There's your error.

Remember you can use

NSLog(@"%s", __PRETTY_FUNCTION__);

to show where you log message is coming from. Their also exists a line and file macro, but normally the function macro should help you enough.

Example:

NSLog(@"%s Before", __PRETTY_FUNCTION__);
[myArray objectAtIndex:anIndex];
NSLog(@"%s After", __PRETTY_FUNCTION__);

If your second log message doesn't come through, then you'll have found your error.

Upvotes: 1

agilityvision
agilityvision

Reputation: 7931

It is always best to use the setter and getter methods for your instance variables. It takes care of a lot of problems. My guess is that is your problem. So anywhere you want to use harvestRecipeList use self.harvestRecipeList It would be useful to know what your property declaration is for harvestRecipeList

Upvotes: 0

Related Questions