2013-03-09 10 views
46

Non sono sicuro di dove si trovi l'errore, dopo aver esaminato altri problemi simili. Ho ricevuto un errore di asserzione.Errore di asserzione in UITableView configureCellForDisplay: forIndexPath:

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

Penso che sia qualcosa di semplice ma spero che qualcuno possa aiutare.

Qui di seguito è il mio codice:

#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; 

} 
+0

Si prega di aggiornare la domanda per indicare quale linea sta causando l'eccezione. Se non lo sai, imposta i breakpoint e fai il codice finché non trovi la linea esatta. –

+0

Beh, sono nuovo di xcode, quindi non sono sicuro di queste cose, ma in questo caso non vengono visualizzati errori e il programma viene eseguito ma si blocca quando seleziono la pagina pertinente? Quindi non so quale linea è l'errore se questo ha senso? Presumerei - (UITableViewCell *) tableView: (UITableView *) tableView cellForRowAtIndexPath: (NSIndexPath *) indexPath; –

+0

Esiste effettivamente una cella con l'identificatore (con distinzione tra maiuscole e minuscole) @ "cella"? – sapi

risposta

103

non siete mai creando una cella, basta cercare di riutilizzare una cella rimosse dalla coda. ma come non l'hai mai creato, non ce n'è.

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

o provare (solo 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; 
} 

da 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: sarà sempre bisogno di un controllo, se è stato restituito una cella, mentre
-dequeueReusableCellWithIdentifier:forIndexPath: può creare un'istanza nuova.

+2

Quello che sta facendo è perfettamente a posto. 'dequeueReusableCellWithIdentifier' creerà la cella se non esiste. – sapi

+9

@sapi non è così, creerà solo una cella se si utilizzano prototipi di storyboard o si è registrato un pennino o una classe per il riutilizzo. – jrturton

+1

È vero, ma se sta seguendo un tutorial è estremamente probabile che stia utilizzando i prototipi (o ci sta provando, ma non ne ha definito uno). Questo è anche ciò che si aspettano gli stub di codice predefiniti per 'UITableViewController'. – sapi

13

Se non è stata definita una cella di prototipo con l'identificatore @"cell" in Storyboard, verrà generato un errore di asserzione quando si tenta di deselezionarlo.

È possibile risolvere questo problema impostando la proprietà Identifier nella cella del prototipo (selezionare la cella e impostare tale attributo nel pannello di destra).

+0

Questo potrebbe sembrare scioccante, ma non sto usando gli storyboard? C'è qualcos'altro che posso fare? E perché le persone votano la mia domanda, consigli su come migliorare? Per il suo difficile iniziare questo linguaggio da un background non di programmazione. Grazie –

+0

Se non stai usando Storyboard, vedi il commento di @ jrturton sulla risposta di vikingosegundo. – sapi

+1

Grazie. Ho accidentalmente impostato il "restauro i.d." nell'identificatore di identità a "cella" anziché "identificatore" nell'ispezione degli attributi. –

0

è necessario chiamare "initWithStyle" in costume TableViewCell e inizializzare di nuovo gli oggetti.

Esempio: file di ProductTableViewCell.m

@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; 
} 

Nel file principale implementazione

- (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; 
} 
0

ho avuto lo stesso errore, e sono riuscito a trovare il guasto. Ho avuto un array per le segues e visualizzare i titoli:

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]; 

Ho quindi utilizzato questo array come l'origine dati per il mio tavolo. L'errore che stavo ricevendo era dovuta al fatto che non ho, infatti, ha avuto la HelpViewSegue dichiarato nel mio Storyboard quando un'istanza della VC:

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

piuttosto banale, ma era piuttosto frustrante! Spero che questo abbia aiutato.

-1

Nel codice qui sotto che hai scritto @"cell" (scritto con un piccolo c), ma è necessario utilizzare @"Cell" (C deve essere capitale).

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

Un molto stupido errore che avevo fatto era

non ho messo l'UITableViewDelegate, UITableViewDataSource dopo il nome della classe controller come mio codice classe era classe TagsViewController: UIViewController

dovrebbe avere classe TagsViewController: UIViewController, UITableViewDelegate, UITableViewDataSource

Potrebbe essere uno di voi è di fronte a causa di questo tutto il codice era ok.

+0

Grazie, ho fatto lo stesso errore. Risolto! –

+0

Welsome @HardikDarji –

Problemi correlati