[Résolu] Ajouter une ligne dans un tableau
Je cherche à faire quelque chose qui a priori est super simple mais je bloque sans comprendre pourquoi :
J'ai le code suivant :
stories est déclaré comme un NSMutableArray et me renvoie 2 (normal il contient 2 éléments).
Mon tableau contient une première cellule spécifique qui va renvoyer des informations et ensuite n cellules avec les informations contenues dans stories. (n étant égale au nombre d'éléments dans stories).
J'ai donc écrit le code suivant :
Qui me renvoie l'erreur suivante à l'exécution :
J'ai donc essayé comme ceci :
Qui plante sans renvoyer d'erreurs.
Qu'est-ce que je ne fait pas correctement ? Est-ce que vous avez une idée de comment faire pour que ça fonctionne ?
Merci d'avance pour vos lumières,
Pierre
J'ai le code suivant :
(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {<br /> return [stories count];<br />}
stories est déclaré comme un NSMutableArray et me renvoie 2 (normal il contient 2 éléments).
Mon tableau contient une première cellule spécifique qui va renvoyer des informations et ensuite n cellules avec les informations contenues dans stories. (n étant égale au nombre d'éléments dans stories).
J'ai donc écrit le code suivant :
(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {<br /> return [stories count]+1;<br />}
Qui me renvoie l'erreur suivante à l'exécution :
*** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[NSCFArray objectAtIndex:]: index (2) beyond bounds (2)'
J'ai donc essayé comme ceci :
// Customize the number of rows in the table view.<br />- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {<br /> NSInteger *numberOfRows = [stories count] + 1;<br /> [numberOfRows autorelease];<br /> return numberOfRows;<br />}
Qui plante sans renvoyer d'erreurs.
Qu'est-ce que je ne fait pas correctement ? Est-ce que vous avez une idée de comment faire pour que ça fonctionne ?
Merci d'avance pour vos lumières,
Pierre
Connectez-vous ou Inscrivez-vous pour répondre.
Réponses
En effet, maintenant tu renvoies 3 au lieu de 2, mais j'imagine que tu n'as pas modifié ton cellForRowAtIndexPath qui va toujours chercher l'élément n°indexPath.row de ton tableau "stories"... donc comme tu lui as dit qu'il y avait 3 lignes, si tu n'as pas changé ton implémentation il demande l'élément 0, puis l'élément 1, et... l'élément 2
il faut que tu adaptes ton code cellForRowAtIndexPath pour que si indexPath.row == 0 alors tu mets ta cellule spéciale, sinon, tu mets tes cellules avec le contenu de l'élément...indexPath.row-1 de stories, du coup
NSInteger n'est pas un objet.
Il faut que tu révises tes cours de C, la partie sur les pointeurs.
@Céroce : si mes souvenirs sont bons "NSInteger" n'existe pas en C (j'espère que je dit pas de connerie ^^) mais seulement en Objective-C. Je savait pas que ce n'est pas un objet.
Je ne voit pas le rapport avec les pointeurs, j'ai sûrement écrit une grosse co**erie mais je ne voit pas laquelle, peut-tu éclaire ma lanterne ?
Merci pour votre aide,
Pierre
tu devrais avoir
Car NSInteger n'est pas un objet donc tu ne peux pas faire une référence par pointeur sur un "non objet" D'ailleurs la méthode le précise. Les NSInteger ne sont pas des pointeurs.
Effectivement. Mais si tu fais un "command-clic-clic" dessus, tu auras vite l'explication
[pre]#if __LP64__ || NS_BUILD_32_LIKE_64
typedef long NSInteger;
typedef unsigned long NSUInteger;
#else
typedef int NSInteger;
typedef unsigned int NSUInteger;
#endif[/pre]
C'est un simple typedef qui permet d'uniformiser le code selon qu'on est en 32 ou 64 bits. En effet, le modèle 64 bits choisi par Apple est le LP64 : les long et les pointeurs passent en 64 bits, mais pas les int. NSInteger permet donc d'uniformiser le code pour les deux environnements.
@lgriffie : ok je comprend mieux ce que dit @Céroce maintenant. C'est bien la ligne :
qui faisait planter mon code.
Ensuite "cellForRowAtIndexPath" me renvoie l'erreur :
que j'ai tout de suite corrigé avec l'aide de @AliGator !
Donc maintenant ça marche, merci à tous !
Pierre
Donc en un sens, si, le type qui se cache derrière NSInteger (puisque c'est un typedef) existe en C.
Le rapport avec les pointeurs ? Tu utilises NSInteger comme si c'était un objet Cocoa, avec la notation pointeur (la petite étoile) : "NSInteger*".
Au final ton code :
1) récupère [tt][stories count]+1[/tt] (donc des valeurs comme 3 ou 4), qui est un NSInteger (type retourné par la méthode "count" de NSArray)... dans un pointeur NSInteger* (donc une adresse mémoire sensée pointer vers un NSInteger) au lieu de récupérer la valeur directement... déjà il y a une erreur de type qui doit t'être signalée par un warning à ce niveau (genre "implicit cast from integer to pointer" ou un truc dans ce goût là )
2) tu envoies un message autorelease à ce NSInteger*, donc à cette adresse mémoire 0x00000003 ou 0x00000004 (donc il s'attend à y trouver un objet Cocoa à qui envoyer ce "autorelease", alors qu'à cette adresse mémoire je sais pas ce qu'il y a mais certainement pas ce que tu y attend... y'a déjà des chances que ça plante ici)... tu devrais déjà avoir un 2e warning te disant que "NSInteger" n'est pas un NSObject, ou que "NSInteger* may not respond to autorelease", ou un truc comme ça, enfin un warning t'indiquant que tu ne devrais pas à envoyer de message autorelease à un truc qui n'est pas un NSObject.
3) et en plus après tu retournes un type de données "NSInteger*" en sortie de ta méthode, alors que le type de retour attendu est juste "NSInteger"... et tu devrais donc avoir un 3e warning t'indiquant ce problème de non-correspondance de type de retour.
Donc avec ces 3 warnings, un warning sur chaque ligne de ta méthode "tableView:numberOfRowsInSection:", ça aurait dû te poser des questions et te mettre sur la voie avec tout ça !
J'ai encore appris un truc sur l'objective-C aujourd'hui. (mode:faut pas rêver non plus) Si ça se trouve je vais finir dieux du code.(/mode:faut pas rêver non plus)
En tout cas merci pour votre patience et vos explication de qualités.
Je retourne à mon code,
Pierre