Reputation: 1295
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
Reputation: 5891
Updated Solution:
So I have checked your code and found the problem. Do the following:
Static Cells
to Dynamic Prototypes
Cell
into Identifier field (this is what you are using as a cell IDNone
to Disclosure Indicator
tableView:numberOfRowsInSection
return self.harvestRecipeList.count
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;
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?
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.tableView:numberOfRowsInSection:
you should return self.harvestRecipeList.count
cell == nil
as dequeueReusableCellWithIdentifier:
is guaranteed to return non-nil cell. You do need to check if you are on the iOS4 SDK.@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
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:
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
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
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