50

I'm not sure where the error is here, having looked at other similar issues. I received an Assertion failure.

Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: UITableView dataSource must return a cell from tableView:cellForRowAtIndexPath:

I think it is something simple but hope someone can help.

Below is my code:

#import "StockMarketViewController.h"

@interface StockMarketViewController ()

@end


@implementation StockMarketViewController
@synthesize ShareNameText, ShareValueText, AmountText;
@synthesize shares, shareValues;


- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section;
{
    return [shares count];

}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath;
{
    UITableViewCell * cell = [tableView dequeueReusableCellWithIdentifier:@"cell"];



    NSString *currentValue = [shareValues objectAtIndex:[indexPath row]];
    [[cell textLabel]setText:currentValue];
    return cell;

}
Sanoj Kashyap
  • 5,020
  • 4
  • 49
  • 75
Jason Taylor
  • 553
  • 1
  • 5
  • 10
  • Please update your question to mark which line is causing the exception. If you don't know, set breakpoints and step through the code until you find the exact line. – David Ravetti Mar 09 '13 at 13:34
  • Well i am new to xcode so i am unsure with these things, but in this case, there are no errors appear, and program runs but crashes when I select the relevant page? So i dont know which line is the error if that makes sense? I would presume - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath; – Jason Taylor Mar 09 '13 at 13:39
  • Is there actually a cell with the (case-sensitive) identifier @"cell"? – sapi Mar 09 '13 at 13:41
  • if not would that cause an issue? As I said i am very new to this, and was using tutorials to assist me and that was part of the code they used. – Jason Taylor Mar 09 '13 at 13:44
  • Do not forget to change the property of the Content > Dynamic Prototypes in the UITableView. – Alexander Oct 02 '13 at 13:28
  • You get this assertion when you return **nil** to `- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath` – SwiftArchitect Jul 21 '14 at 22:43

6 Answers6

108

you are never creating a cell, you just try to reuse a dequeued cell. but as you never created one, there is none.

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath;
{
    static NSString *cellIdentifier = @"cell";
    UITableViewCell * cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
    if (!cell) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellIdentifier];
    }

    NSString *currentValue = [shareValues objectAtIndex:[indexPath row]];
    [[cell textLabel]setText:currentValue];
    return cell;
}

or try (only iOS 6+)

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath;
{
    static NSString *cellIdentifier = @"cell";
    UITableViewCell * cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier forIndexPath:indexPath];

    NSString *currentValue = [shareValues objectAtIndex:[indexPath row]];
    [[cell textLabel]setText:currentValue];
    return cell;
}

from UITableView.h

- (id)dequeueReusableCellWithIdentifier:(NSString *)identifier;  // Used by the delegate to acquire an already allocated cell, in lieu of allocating a new one.
- (id)dequeueReusableCellWithIdentifier:(NSString *)identifier 
                           forIndexPath:(NSIndexPath *)indexPath NS_AVAILABLE_IOS(6_0); // newer dequeue method guarantees a cell is returned and resized properly, assuming identifier is registered

-dequeueReusableCellWithIdentifier: will always need a check, if a cell was returned, while
-dequeueReusableCellWithIdentifier:forIndexPath: can instantiate new one.

vikingosegundo
  • 52,040
  • 14
  • 137
  • 178
  • 2
    What he's doing is perfectly okay. `dequeueReusableCellWithIdentifier` will create the cell if it does not exist. – sapi Mar 09 '13 at 13:58
  • 9
    @sapi not so, it will only create a cell if you are using storyboard prototypes or have registered a nib or class for reuse. – jrturton Mar 09 '13 at 13:59
  • 1
    True, but if he's following a tutorial it's extremely likely that he's using prototypes (or is trying to, but hasn't defined one). That's also what the default code stubs for `UITableViewController` expect. – sapi Mar 09 '13 at 14:01
  • 1
    @sapi, you mean - (id)dequeueReusableCellWithIdentifier:(NSString *)identifier forIndexPath:(NSIndexPath *)indexPath NS_AVAILABLE_IOS(6_0); // newer dequeue method guarantees a cell is returned and resized properly, assuming identifier is registered – vikingosegundo Mar 09 '13 at 14:03
  • I did indeed mean that. Sorry about the mistake, maybe I should get some sleep :) – sapi Mar 09 '13 at 14:06
  • If I wanted to display a value beside a share price, what way do i go about that? – Jason Taylor Mar 09 '13 at 14:15
  • either use a appropriate style or create a custom cell. https://developer.apple.com/library/ios/#documentation/UserExperience/Conceptual/TableView_iPhone/AboutTableViewsiPhone/AboutTableViewsiPhone.html – vikingosegundo Mar 09 '13 at 14:20
  • @JasonTaylor - one thing to be aware of in following a book or tutorial on iOS/Objective-C/Xcode ... things change very quickly and books/tutorials in this area can become outdated on almost a yearly basis. As noted in the answer/comments above iOS6 has a slightly different way of handling UITableViewCells. It's not always possible to find an up-to-date version of a given tutorial, but whenever you can it will save you a lot of grief. (Spoken as someone with a shelf of Cocoa/Objective-C books he planned to get to someday only to find out they were obsolete when "someday" finally came.) – David Ravetti Mar 09 '13 at 14:51
  • Thanks, I have inserted a newsfeed table, a shares table, both using plists. I need to include share value in share table and depending on the severity of the newsfeed then this share value will change accordingly. I am doing this for my final year project at University, and there are no lecturers who have xcode knowledge so I appreciate any advice that i can get as Im alone on this and only started xcode at christmas time. Thanks for any feedback. – Jason Taylor Mar 09 '13 at 15:31
  • One caveat that happened with me was I realized that I was programmatically newing up a controller. What I needed to do instead was use UIStoryboard to instantiateViewControllerWithIdentifier to access it from the storyboard. Only then did it have the table, prototype cells, etc. – Canucklesandwich Mar 12 '16 at 22:50
13

If you have not defined a prototype cell with the identifier @"cell" in Storyboard, you will get an assertion error when you attempt to dequeue it.

You can fix this by setting the Identifier property on the prototype cell (select the cell and set that attribute in the right hand panel).

sapi
  • 9,944
  • 8
  • 41
  • 71
  • This might sound shocking, but i am not using storyboards? Is there anything else i can do? And why are people voting down my question, advice how to improve? For its tough starting this language from a non programming background. Thanks – Jason Taylor Mar 09 '13 at 14:01
  • If you're not using Storyboards, see @jrturton's comment on vikingosegundo's answer. – sapi Mar 09 '13 at 14:02
  • 1
    Thank you. I had accidentally set the "restoration i.d." in the identity inspector to "cell" rather than the "identifier" in the attributes inspection. – Joe Fratianni Jul 15 '14 at 17:01
7

A very silly mistake i had done was

i didn't put the UITableViewDelegate, UITableViewDataSource after the controller class name like my class code was class TagsViewController: UIViewController

it should have class TagsViewController: UIViewController , UITableViewDelegate, UITableViewDataSource

May be one of you is facing due to this all other code was ok.

OurangZeb Khan
  • 1,114
  • 18
  • 20
0

You need to call "initWithStyle" in custom TableViewCell and initialise the objects again.

Example: ProductTableViewCell.m file

@implementation ProductTableViewCell

- (void)awakeFromNib {
}

- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
   [super setSelected:selected animated:animated];
}

- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
    if (self = [super initWithStyle:style reuseIdentifier:reuseIdentifier])
    {
        self.selectionStyle = UITableViewCellSelectionStyleNone;
        _titleLabel = [[UILabel alloc] initWithFrame:(CGRectMake(70, 0, 320, 60))];
        [self.contentView addSubview:_titleLabel];
   }
   return self;
}

In the main implementation file

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ 
    ProductTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"productTableViewCell"];
    NSDictionary *dic = nil;
    if (tableView == self.searchDisplayController.searchResultsTableView) {
        dic = [_filteredArray objectAtIndex:indexPath.row];
    } else {
        dic = [_originalArray objectAtIndex:indexPath.row];
    }
    cell.titleLabel.text = [dic objectForKey: @"title"];
    return cell;
}
user1802778
  • 81
  • 1
  • 2
0

I had the same error, and I managed to find the fault. I had an array for the segues and view titles:

NSArray *MMTitles= [NSArray arrayWithObjects:@"MainMenu",@"viewIt",@"viewNots",@"MyProfile",@"Settings",@"Instructions",@"Help", nil];
NSArray *MMSegues=[NSArray arrayWithObjects:@"MainMenu",@"MyProfileSegue",@"viewNotSegue",@"MyProfileSegue",@"SettingsTableViewSegue",@"InstructionsViewSegue",@"HelpViewSegue", nil];

self.menuItems = [[NSArray alloc]initWithObjects:MMTitles,MMSegues, nil];

I then used this array as the datasource for my table. The error I was receiving was due to the fact that I didn't in fact had the HelpViewSegue declared in my Storyboard when I instantiated the VC:

    vc = [mainStoryboard instantiateViewControllerWithIdentifier: [[self.menuItems objectAtIndex:1]objectAtIndex:indexPath.row]];

Pretty trivial, but it was pretty frustrating! Hope this helped.

Septronic
  • 1,156
  • 13
  • 32
-2

In the below code you have written @"cell" (written with a small c), but you have to use @"Cell" (C must be capital).

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath;
{
    UITableViewCell * cell = [tableView dequeueReusableCellWithIdentifier:@"Cell"];
AlBlue
  • 23,254
  • 14
  • 71
  • 91