Organiser les cellules d'un TableView

Bonjour



J'ai un petit problème dans la réorganisation des cellules de mon TableView. J'utilise la méthode "- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath" comme indiqué dans la doc Apple. Puis j'utilise ce bout de code pour bouger mes cellules de place :
<br />
- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath {<br />
	return YES;<br />
}<br />
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath<br />
toIndexPath:(NSIndexPath *)toIndexPath {<br />
	NSString *item = [pile objectAtIndex:fromIndexPath.row];<br />
	[pile removeObject:item];<br />
	[pile insertObject:item atIndex:toIndexPath.row];<br />
}<br />




Mais dès que je bouge certaines cellules, mon application plante et la console me dit : "Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[__NSArrayM insertObject:atIndex:]: index 2 beyond bounds for empty array"

Et là  je n'arrive pas à  aller plus loin.



Quelqu'un aurait-il une idée sur la question ?



Merci image/smile.png' class='bbc_emoticon' alt=':)' />
Mots clés:

Réponses

  • AliGatorAliGator Membre, Modérateur
    As-tu pensé que quand tu enlèves un objet de ton tableau (pile), cela décale les indexes ? Cela peut être la cause de surprises.





    Bon je ne suis pas sûr que ce soit ça car l'exception parle d'un NSRangeException certes, mais pour l'index 2 sur un empty array, et pas sur un array contenant qu'un élément comme ça serait le cas si c'était à  cause de ça... mais n'empêche que ça ne fais pas de mal de corriger ça déjà 



    Pense aussi que quand tu supprimes ton object "item" de ta pile avec removeObject, plus personne ne le retain, donc potentiellement il peut être désalloué et disparaà®tre de la mémoire avant même que tu aies le temps de le réinsérer dans ta pile au nouvel emplacement.



    Bien sûr, si tu utilises ARC tu n'auras pas de problème, car ARC est suffisamment intelligent pour insérer les retain/release nécessaires aux bons endroits pour éviter les risques de ce côté. Mais si tu n'utilises pas ARC, il faut penser à  faire un retain avant de faire le removeObject pour garder l'item de côté, le temps de faire le insertObject:atIndex, puis ensuite tu pourras relâcher item avec un release. Ou alors faire le insert avant le remove, mais dans ce cas encore une fois attention aux risques de décalage des indexs.



    Et sinon au final pour résoudre ton bug, bah... mets des breakpoints et regarde ce que contient ta pile avant le insertObject qui pourrait expliquer le crash.
  • Alors j'ai regardé ce que contenait "pile" à  différent moment et j'ai constaté un petit truc, il fallait juste lui dire d'enlever l'objet à  un certain index et ça arche très bien maintenant. Voici mon code :
    <br />
    - (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath<br />
    toIndexPath:(NSIndexPath *)toIndexPath {<br />
        NSString *item = [pile objectAtIndex:fromIndexPath.row];<br />
        [pile insertObject:item atIndex:toIndexPath.row];<br />
        [pile removeObjectAtIndex:toIndexPath.row];<br />
    }<br />
    
  • Alf1996Alf1996 Membre
    novembre 2012 modifié #4
    +1 pour Ali pour le retain...

    J'ai eu exactement le même problème il n'y a pas très longtemps, et en relisant bien la doc, il y a un retain dans l'exemple fourni (malheureusement je ne retrouve pas le lien). Sans le retain/release, j'avais un fonctionnement aléatoire...

    Par contre, je ne sais pas si tu utilises ARC... Dans ce cas, c'est peut-être différent...

    Par contre, si tu insères l'item avant de faire le remove, tu risques d'avoir des surprises au niveau des index de ton tableau (si tu déplaces une ligne de la fin de la table vers le début).

    Avec ce bout de code, pas de problème :
    <br />
    [color=#666600]-[/color][color=#000000] [/color][color=#666600]([/color][color=#000088]void[/color][color=#666600])[/color][color=#000000]tableView:[/color][color=#666600] ([/color][color=#660066]UITableView[/color][color=#000000] [/color][color=#666600]*)[/color][color=#000000]tableView moveRowAtIndexPath:[/color][color=#666600] ([/color][color=#660066]NSIndexPath[/color][color=#000000] [/color][color=#666600]*)[/color][color=#000000]fromIndexPath<br />
    toIndexPath[/color][color=#666600] : ([/color][color=#660066]NSIndexPath[/color][color=#000000] [/color][color=#666600]*)[/color][color=#000000]toIndexPath [/color][color=#666600]{[/color]<br />
    [color=#000000]	[/color][color=#660066]NSString[/color][color=#000000] [/color][color=#666600]*[/color][color=#000000]item [/color][color=#666600]=[/color][color=#000000] [[/color][color=#666600][[/color][color=#000000]pile objectAtIndex[/color][color=#666600]:[/color][color=#000000]fromIndexPath[/color][color=#666600].[/color][color=#000000]row[/color][color=#666600]] retain];[/color]<br />
    [color=#000000]	[/color][color=#666600][[/color][color=#000000]pile removeObjectAtIndex[/color][color=#666600]:from[/color][color=#000000]IndexPath[/color][color=#666600].[/color][color=#000000]row[/color][color=#666600]];[/color]<br />
    [color=#666600][color=#000000]	[/color][color=#666600][[/color][color=#000000]pile insertObject[/color][color=#666600]:[/color][color=#000000]item atIndex[/color][color=#666600]:[/color][color=#000000]toIndexPath[/color][color=#666600].[/color][color=#000000]row[/color][color=#666600]];[/color]<br />
       [item release];[/color]<br />
    [color=#666600]}[/color]<br />
    






    Edit : çà  y est j'ai retrouvé la doc en question :



    http://developer.apple.com/library/ios/#documentation/UserExperience/Conceptual/TableView_iPhone/ManageReorderRow/ManageReorderRow.html#//apple_ref/doc/uid/TP40007451-CH11-SW1
  • C'est cette page là  de la doc que j'étais allé voir. Moi j'ai appris objective-c avec Xcode 4. C'est relativement récent. J'ai donc appris avec StoryBoard (mais je sais aussi faire sans) et avec ARC qui est, je crois, activé par défaut depuis Xcode 4.
  • Alors si tu utilises la même page de la doc, n'hésite pas à  la relire, car la solution à  ton problème y est donnée... comme bien souvent !!! image/wink.png' class='bbc_emoticon' alt=';)' />
Connectez-vous ou Inscrivez-vous pour répondre.