views:

289

answers:

2

I'm going through the Beginning iPhone Development book & stuck in chapter 9. I've spent a few hours trying to debug this error w/o avail:

2010-05-01 19:27:51.361 Nav2[4113:20b] *** Assertion failure in -[UITableView _createPreparedCellForGlobalRow:withIndexPath:], /SourceCache/UIKit/UIKit-984.38/UITableView.m:4709
2010-05-01 19:27:51.362 Nav2[4113:20b] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'UITableView dataSource must return a cell from tableView:cellForRowAtIndexPath:'
2010-05-01 19:27:51.364 Nav2[4113:20b] Stack: (
 ...
)

I'm not looking for help w/ the book, but tips for how to debug this error? Can I pin down which of my cellForRowAtIndexPath methods is the problem? And how to inspect the type? Or other things should I look at?

Edit: As requested, the code for the two suspect methods:

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

    static NSString *RootViewControllerCell = @"RootViewControllerCell";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:RootViewControllerCell];
    if (cell == nil) {
        cell == [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:RootViewControllerCell] autorelease];
    }

    NSUInteger row = [indexPath row];
    SecondLevelViewController *controller = [controllers objectAtIndex:row];
    cell.textLabel.text = controller.title;
    cell.image = controller.rowImage;
    return cell;
}

--

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

    static NSString * DisclosureButtonCellIdentifier = 
    @"DisclosureButtonCellIdentifier";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier: 
                             DisclosureButtonCellIdentifier];
    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault 
                                       reuseIdentifier: DisclosureButtonCellIdentifier]
                autorelease];
    }
    return cell;

    NSUInteger row = [indexPath row];
    NSString *rowString = [list objectAtIndex:row];
    cell.textLabel.text = rowString;
    cell.accessoryType = UITableViewCellAccessoryDetailDisclosureButton;
    [rowString release];
    return cell;
}
+1  A: 

One of the best ways would be to set breakpoints on the first line of all the cellForRowAtIndexpath: methods, then run the code with debugging enabled. Do whatever invokes the exception and you should pop into your method quickly.

Once you're in debugging, step through the method. You can use "po objectname" to get information on various objects as they are referenced from within your method. It's straightforward to invoke from the console, and you might get what you need from just hovering the mouse over the variables as you are stepping through the code.

At a guess, you are not returning a UITableViewCell out of your method.

heckj
Ah, that does help. I set a breakpoint on both return statements. In in the first, I find that cell is basically null:(gdb) p cell$1 = (UITableViewCell *) 0x0So it seems that ' cell == [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:RootViewControllerCell] autorelease]; ' is failing?
Bill
+3  A: 

You have an extra equals sign, i.e.:

cell == [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:RootViewControllerCell] autorelease];

should be:

cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:RootViewControllerCell] autorelease];
Alex Reynolds
KAAAAAAAAAAAAAAAAHHHHHHHHHHHHHHHNNNNNNNNNNNNNNN!!!!!!!!!!!!!!!!!!!!!! Seriously, thank you to you both.
Bill