324 votes

Échec de l'assertion dans dequeueReusableCellWithIdentifier:forIndexPath :

Je faisais un lecteur rss pour mon école et j'ai fini le code. J'ai lancé le test et il m'a donné cette erreur. Voici le code auquel il se réfère :

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

        cell = 
         [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle  
                                reuseIdentifier:CellIdentifier];

    }

Voici l'erreur dans la sortie :

2012-10-04 20:13:05.356 Lecteur [4390:c07] * Échec d'assertion dans -[UITableView dequeueReusableCellWithIdentifier:forIndexPath :], /SourceCache/UIKit_Sim/UIKit-2372/UITableView.m:4460 2012-10-04 20:13:05.357 Reader [4390:c07] * Arrêt de l'application en raison d'une exception exception 'NSInternalInconsistencyException', reason : 'unable to dequeue a cell with identifier Cell - must register a nib or a class for the identifier or connect a prototype cell in a storyboard'. pour l'identifiant ou connecter une cellule prototype dans un storyboard'. * Pile du premier appel lancé : (0x1c91012 0x10cee7e 0x1c90e78 0xb64f35 0xc7d14 0x39ff 0xd0f4b 0xd101f 0xb980b 0xca19b 0x6692d 0x10e26b0 0x228dfc0 0x228233c 0x228deaf 0x1058cd 0x4e1a6 0x4ccbf 0x4cbd9 0x4be34 0x4bc6e 0x4ca29 0x4f922 0xf9fec 0x46bc4 0x47311 0x2cf3 0x137b7 0x13da7 0x14fab 0x26315 0x2724b 0x18cf8 0x1becdf9 0x1becad0 0x1c06bf5 0x1c06962 0x1c37bb6 0x1c36f44 0x1c36e1b 0x147da 0x1665c 0x2a02 0x2935) libc++abi.dylib : terminate appelé en lançant une exception

et voici le code qu'il affiche dans l'écran d'erreur :

int main(int argc, char *argv[])
{
    @autoreleasepool {
        return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
    }
}

Aidez-nous !

0 votes

489voto

rob mayoff Points 124153

Vous utilisez le dequeueReusableCellWithIdentifier:forIndexPath: méthode. Le site documentation pour cette méthode dit ceci :

Important : Vous devez enregistrer une classe ou un fichier nib à l'aide de la fonction registerNib:forCellReuseIdentifier: o registerClass:forCellReuseIdentifier: avant d'appeler cette méthode.

Vous n'avez pas enregistré une plume ou une classe pour l'identifiant de réutilisation. "Cell" .

En regardant votre code, vous semblez vous attendre à ce que la méthode dequeue renvoie nil s'il n'a pas de cellule à vous donner. Vous devez utiliser le dequeueReusableCellWithIdentifier: pour ce comportement :

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

Remarquez que dequeueReusableCellWithIdentifier: y dequeueReusableCellWithIdentifier:forIndexPath: sont des méthodes différentes. Voir la doc pour l'ancien y ce dernier .

Si vous voulez comprendre pourquoi vous voudriez jamais utiliser dequeueReusableCellWithIdentifier:forIndexPath: , consultez ce Q&R .

166 votes

OMG. Pourquoi le modèle par défaut de Xcode pour un UITableViewController vous donne automatiquement dequeueReusableCellWithIdentifier:forIndexPath: ? C'est tellement inutile.

15 votes

Le site dequeueReusableCellWithIdentifer:forIndexPath: (introduit dans iOS6) est une amélioration intéressante, puisque vous n'avez pas besoin de vérifier si la cellule est nulle. (Ainsi UITableViewController fonctionne de la même manière que UICollectionView ) Mais oui, c'est ennuyeux que ce changement ne soit pas commenté dans le modèle et que l'assertion/le message d'erreur ne soit pas plus utile.

2 votes

Au minimum, on pourrait penser qu'il serait par défaut UITableViewCell au lieu d'imploser. Baka.

138voto

Je pense que cette erreur concerne l'enregistrement de votre plume ou classe pour l'identifiant.

Ainsi, vous pouvez conserver ce que vous faites dans votre fonction tableView:cellForRowAtIndexPath et ajouter le code ci-dessous dans votre viewDidLoad :

[self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:@"Cell"];

Cela a fonctionné pour moi. J'espère que cela pourra vous aider.

69voto

Bien que cette question soit assez ancienne, il existe une autre possibilité : Si vous utilisez des Storyboards, vous devez simplement définir le CellIdentifier dans le Storyboard.

Ainsi, si votre CellIdentifier est "Cell", il suffit de définir la propriété "Identifier" : enter image description here

Assurez-vous de nettoyer votre construction après avoir fait cela. XCode a parfois des problèmes avec les mises à jour de Storyboard.

3 votes

Tu es génial, le nettoyage fait beaucoup ! !! :D

2 votes

Remarque - si vous utilisez un identifiant autre que "Cell", vous devrez également modifier votre méthode cellForRowAtIndexPath pour utiliser cet identifiant dans la ligne suivante : static NSString *CellIdentifier = @ "MyCellIdentifier" ;

5 votes

Un complément important à cela : L'attribut "Content" de la vue tableau doit être défini sur "Dynamic Prototypes", et NON sur "Static Cells".

59voto

iMeMyself Points 1247

J'ai eu le même problème en le remplaçant par

static NSString *CellIdentifier = @"Cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

   if (cell==nil) {
        cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];

    }

résolu

0 votes

Merci. Cela vient de m'éviter un mal de tête. =)

3 votes

Conseil : si vous utilisez un -(id)dequeueReusableCellWithIdentifier:forIndexPath : Il n'est pas nécessaire de vérifier si la cellule est nulle. (IOS6>)

0 votes

Vous venez de m'épargner un mal de tête. =)

27voto

James Wang Points 71

Le problème est probablement dû au fait que vous configurez des UITableViewCell dans storyboard mais vous n'utilisez pas storyboard pour instancier votre UITableViewController qui utilise cette UITableViewCell . Par exemple, dans le MainStoryboard, vous avez une UITableViewController sous-classe appelée MyTableViewController et avoir une dynamique personnalisée UITableViewCell appelé MyTableViewCell avec l'identifiant "MyCell".

Si vous créez votre propre UITableViewController comme ça :

 MyTableViewController *myTableViewController = [[MyTableViewController alloc] init];

Il n'enregistrera pas automatiquement votre tableviewcell personnalisée pour vous. Vous devez l'enregistrer manuellement.

Mais si vous utilisez le storyboard pour instancier MyTableViewController comme ceci :

UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil];
MyTableViewController *myTableViewController = [storyboard  instantiateViewControllerWithIdentifier:@"MyTableViewController"];

Une belle chose arrive ! UITableViewController enregistrera automatiquement pour vous votre cellule de tableview personnalisée que vous avez définie dans le storyboard.

Dans votre méthode déléguée "cellForRowAtIndexPath", vous pouvez créer votre cellule de vue de table comme ceci :

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

//Configure your cell here ...

return cell;
}

dequeueReusableCellWithIdentifier créera automatiquement une nouvelle cellule pour vous s'il n'y a pas de cellule réutilisable disponible dans la file de recyclage.

Ensuite, vous avez terminé !

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X