web-dev-qa-db-fra.com

Échec d'assertion dans dequeueReusableCellWithIdentifier: forIndexPath:

Je fabriquais donc un lecteur de flux RSS pour mon école et finissais le code. J'ai fait le test et ça m'a donné cette erreur. Voici le code auquel il fait référence:

- (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 Reader [4390: c07] * Échec de l'assertion dans ITableView dequeueReusableCellWithIdentifier: forIndexPath:], /SourceCache/UIKit_Sim/UIKit-2372/UITableView.m:4460 2012-10 -04 20: 13: 05.357 Reader [4390: c07] * Application terminée en raison d'une exception non capturée 'NSInternalInconsistencyException', raison: 'impossible de retirer de la file d'attente avec une cellule Cell - doit enregistrer une plume ou une classe pour l'identificateur ou connecter une cellule prototype dans un story-board " --- [* pile premier appel de lancer: (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 0x2724f 0x18cf8 0x1becdf9 0x1becad0 0x1c06bf5 0x1c06962 0x1c37bb6 0x1c36f44 0x1c36e1b 0x147da 0x1665c 0x2a02 0x2935) libc ++ abi.dylib

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

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

aidez s'il vous plaît!

320
Nick Scottman

Vous utilisez la méthode dequeueReusableCellWithIdentifier:forIndexPath:. La documentation pour cette méthode dit ceci:

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

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

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

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

Notez que dequeueReusableCellWithIdentifier: et dequeueReusableCellWithIdentifier:forIndexPath: sont des méthodes différentes. Voir doc pour le premier et le dernier .

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

487
rob mayoff

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

Pour que vous puissiez garder ce que vous faites dans votre tableView: fonction cellForRowAtIndexPath et juste ajouter du code ci-dessous dans votre viewDidLoad:

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

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

137
user843910

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

Donc, si votre CellIdentifier est "Cell", définissez simplement la propriété "Identifier": enter image description here

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

67
Sebastian Borggrewe

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

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

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

    }

résolu

59
iMeMyself

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

Si vous créez votre UITableViewController personnalisé comme ceci:

 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, procédez comme suit:

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

Belle chose arrive! UITableViewController enregistre automatiquement votre cellule personnalisée tableview que vous définissez dans le storyboard.

Dans votre méthode déléguée "cellForRowAtIndexPath", vous pouvez créer votre cellule de vue tableau de la manière suivante:

- (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 s'il n'y a pas de cellule réutilisable disponible dans la file de recyclage.

Alors vous avez fini!

25
James Wang

J'ajouterai simplement que Xcode 4.5 inclut le nouveau dequeueReusableCellWithIdentifier:forIndexPath:
dans son code de modèle par défaut - un piège potentiel pour les développeurs qui attendent l'ancienne méthode dequeueReusableCellWithIdentifier:.

19
Brian Shriver

Solution Swift 2.0:

Vous devez accéder à votre inspecteur d'attributs et ajouter un nom pour vos cellules. Identifiant:

enter image description here

Ensuite, vous devez faire correspondre votre identifiant avec votre file d'attente comme suit:

let cell2 = tableView.dequeueReusableCellWithIdentifier("ButtonCell", forIndexPath: indexPath) as! ButtonCell

Alternativement

Si vous travaillez avec une nib, vous devrez peut-être enregistrer votre classe dans votre cellForRowAtIndexPath:

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {       

    tableView.registerClass(UITableViewCell.self, forCellReuseIdentifier: "SwitchCell")

    // included for context            
    let cell = tableView.dequeueReusableCellWithIdentifier("SwitchCell", forIndexPath:indexPath) as! SwitchCell

    //... continue    
}

La référence de la classe UITableView d'Apple dit:

Avant de retirer de la file d'attente des cellules, appelez cette méthode ou la méthode registerNib: forCellReuseIdentifier: pour indiquer à la vue tabulaire comment créer de nouvelles cellules. Si une cellule du type spécifié ne se trouve pas actuellement dans une file d'attente de réutilisation, la vue tableau utilise les informations fournies pour créer automatiquement un nouvel objet de cellule.

Si vous avez déjà enregistré un fichier de classe ou un fichier nib avec le même identifiant de réutilisation, la classe que vous spécifiez dans le paramètre cellClass remplace l'ancienne entrée. Vous pouvez spécifier nil pour cellClass si vous souhaitez désenregistrer la classe de l'identificateur de réutilisation spécifié.

Voici le code du framework Apples Swift 2.0:

// Beginning in iOS 6, clients can register a nib or class for each cell.
// If all reuse identifiers are registered, use the newer -dequeueReusableCellWithIdentifier:forIndexPath: to guarantee that a cell instance is returned.
// Instances returned from the new dequeue method will also be properly sized when they are returned.

@available(iOS 5.0, *)
func registerNib(nib: UINib?, forCellReuseIdentifier identifier: String)

@available(iOS 6.0, *)
func registerClass(cellClass: AnyClass?, forCellReuseIdentifier identifier: String)
18
Dan Beaulieu

Dans votre storyboard, vous devez définir l’identificateur de votre cellule prototype identique à votre "Cell" CellReuseIdentifier. Dans ce cas, vous ne recevrez pas ce message ou n’aurez pas besoin d’appeler cette fonction registerClass :.

18
Steven

Travailler avec Swift 3.0:

override func viewDidLoad() {
super.viewDidLoad()

self.myList.register(UINib(nibName: "MyTableViewCell", bundle: nil), forCellReuseIdentifier: "Cell")
}



public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = myList.dequeueReusableCell(withIdentifier: "Cell", for: indexPath as IndexPath) as! MyTableViewCell

return cell
}
3
norbDEV

Si vous utilisez Cellules statiques personnalisées commentez simplement cette méthode:

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

et donnez aux cellules un identifiant à "Inspecteur d'attributs" dans le storyboard.

3

Je vous donne la réponse à la fois dans l’objectif C et dans Swift.Avant je veux dire

Si nous utilisons la méthode dequeueReusableCellWithIdentifier:forIndexPath:, nous devons enregistrer une méthode ou un fichier nib à l'aide de la méthode registerNib: forCellReuseIdentifier: ou registerClass: forCellReuseIdentifier: avant d'appeler cette méthode en tant que Apple Documnetation Says

Nous ajoutons donc registerNib:forCellReuseIdentifier: or registerClass:forCellReuseIdentifier:

Une fois que nous avons enregistré une classe pour l'identificateur spécifié et qu'une nouvelle cellule doit être créée, cette méthode initialise la cellule en appelant sa méthode initWithStyle: reuseIdentifier:. Pour les cellules basées sur nib, cette méthode charge l'objet cellule à partir du fichier nib fourni. Si une cellule existante était disponible pour une réutilisation, cette méthode appelle à la place la méthode prepareForReuse de la cellule.

dans la méthode viewDidLoad nous devrions enregistrer la cellule

Objectif C

OPTION 1:

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

OPTION 2:

[self.tableView registerNib:[UINib nibWithNibName:@"CustomCell" bundle:nil] forCellReuseIdentifier:@"cell"];

dans le code ci-dessus nibWithNibName:@"CustomCell" donnez votre nom de plume au lieu de mon nom de plume CustomCell

Rapide

OPTION 1:

tableView.registerClass(UITableViewCell.self, forCellReuseIdentifier: "cell")

OPTION 2:

tableView.registerNib(UINib(nibName: "NameInput", bundle: nil), forCellReuseIdentifier: "Cell") 

dans le code ci-dessus nibName:"NameInput" donnez votre nom de plume

3
user3182143

J'ai tout configuré correctement dans le Storyboard et ai effectué une construction propre, mais le message d'erreur "vous devez enregistrer un nib ou une classe pour l'identifiant ou connecter une cellule prototype dans un storyboard"

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

Correction de l'erreur mais je suis toujours perdu. Je n'utilise pas de "cellule personnalisée", mais juste une vue avec une table intégrée. J'ai déclaré le contrôleur de vue en tant que délégué et source de données et je me suis assuré que l'identificateur de cellule correspond dans le fichier. que se passe t-il ici?

2
FrostyL

FWIW, j'ai eu la même erreur quand j'ai oublié de définir l'identifiant de la cellule dans le storyboard. Si tel est votre problème, dans le storyboard, cliquez sur la cellule de la vue tableau et définissez l'identifiant de la cellule dans l'éditeur d'attributs. Assurez-vous que l'identifiant de cellule que vous avez défini ici est le même que

static NSString *CellIdentifier = @"YourCellIdenifier";
2
honkskillet

J'ai eu le même problème, était d'avoir la même erreur et pour moi cela a fonctionné comme suit:

[self.tableView registerNib:[UINib nibWithNibName:CELL_NIB_HERE bundle: nil] forCellReuseIdentifier:CELL_IDENTIFIER_HERE];

Peut-être que ce sera utile pour quelqu'un d'autre.

2
CarmenA

La nuit dernière, j'ai passé des heures à comprendre pourquoi ma table générée par programme était bloquée sur [myTable setDataSource: self]; C'était OK de commenter et d'afficher une table vide, mais je me suis écrasé à chaque fois que j'essayais d'atteindre la source de données;

La délégation a été configurée dans le fichier h: @interface myViewController: UIViewController

J'ai eu le code source de données dans mon implémentation et toujours BOOM !, plantage à chaque fois! MERCI à "xxd" (n ° 9): l’ajout de cette ligne de code l’a résolu pour moi! En fait, je lance une table à partir d'un bouton IBAction. Voici donc mon code complet:

    - (IBAction)tapButton:(id)sender {

    UIViewController* popoverContent = [[UIViewController alloc]init];

    UIView* popoverView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 200, 300)];
    popoverView.backgroundColor = [UIColor greenColor];
    popoverContent.view = popoverView;

    //Add the table
    UITableView *table = [[UITableView alloc] initWithFrame:CGRectMake(0, 0, 200, 300)         style:UITableViewStylePlain];

   // NEXT THE LINE THAT SAVED MY SANITY Without it the program built OK, but crashed when      tapping the button!

    [table registerClass:[UITableViewCell class] forCellReuseIdentifier:@"Cell"];
    table.delegate=self;
    [table setDataSource:self];
    [popoverView addSubview:table];
    popoverContent.contentSizeForViewInPopover =
    CGSizeMake(200, 300);

    //create a popover controller
    popoverController3 = [[UIPopoverController alloc]
                          initWithContentViewController:popoverContent];
    CGRect popRect = CGRectMake(self.tapButton.frame.Origin.x,
                                self.tapButton.frame.Origin.y,
                                self.tapButton.frame.size.width,
                                self.tapButton.frame.size.height);


    [popoverController3 presentPopoverFromRect:popRect inView:self.view   permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];



   }


   #Table view data source in same m file

   - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
   {
    NSLog(@"Sections in table");
    // Return the number of sections.
    return 1;
   }

   - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 
  {
    NSLog(@"Rows in table");

    // Return the number of rows in the section.
    return myArray.count;
   }

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

    NSString *myValue;

    //This is just some test array I created:
    myValue=[myArray objectAtIndex:indexPath.row];

    cell.textLabel.text=myValue;
    UIFont *myFont = [ UIFont fontWithName: @"Arial" size: 12.0 ];
    cell.textLabel.font  = myFont;

    return cell;
   }

Au fait: le bouton doit être lié en tant qu'IBAction et en tant qu'IBOutlet si vous souhaitez y ancrer le popover.

UIPopoverController * popoverController3 est déclaré dans le fichier H directement après @interface entre {}

2
Simone

Juste un supplément de réponses: Il se peut qu’à un moment donné, tout soit correct, mais vous pouvez ajouter accidentellement d’autres UI en vous .xib, comme un UIButton: enter image description here Supprimez simplement l'interface utilisateur supplémentaire, cela fonctionne.

1
DrustZ

Assurez-vous que l'identifiant CellIdentifier == de la cellule dans un storyboard, les deux noms sont identiques. J'espère que ça marche pour toi

1
Ankit garg

Cela peut sembler stupide à certaines personnes, mais cela m’a eu. Je recevais cette erreur et le problème pour moi était que j'essayais d'utiliser des cellules statiques, mais que j'ajoutais ensuite dynamiquement d'autres éléments. Si vous appelez cette méthode, vos cellules doivent être des prototypes dynamiques. Sélectionnez la cellule dans le storyboard et sous l'inspecteur Attributs, la première chose à dire "Contenu" et vous devez sélectionner des prototypes dynamiques et non statiques.

1
Chase Roberts

Dans Swift, ce problème peut être résolu en ajoutant le code suivant dans votre

viewDidLoad

méthode.

tableView.registerClass(UITableViewCell.classForKeyedArchiver(), forCellReuseIdentifier: "your_reuse_identifier")
0
arango_86

Dans mon cas, le crash est arrivé quand j'ai appelé deselectRowAtIndexPath:

La ligne était [tableView deselectRowAtIndexPath:indexPath animated:YES];

Le changer en [self.tableView deselectRowAtIndexPath:indexPath animated:YES];FIXED MY PROBLEM!

J'espère que cela aide quelqu'un

0
Offek