demande d'avis et conseils pour optimisation de l'affichage de ma tableview

NackuNacku Membre
janvier 2012 modifié dans API UIKit #1
Bonjour,


ma tableview marche et affiche une liste de tweets récupérer avec en json. Mais je pense que ce n'est pas parfait ! j'aimerais avoir vos avis pour une optimisation. Certains vont peut être y voir des horreurs :p

<br />- (UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {<br /> <br /> static NSString *CellIdentifier = @&quot;CellIdentifier&quot;;<br />&nbsp; Tweet *tw = [listdata objectAtIndex:indexPath.row];<br />&nbsp; &nbsp;  UILabel *label;<br />&nbsp; &nbsp;  UILabel *tweet;<br />&nbsp; &nbsp;  <br /> UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];<br /> if (cell == nil) {<br /> cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];<br /> }<br />&nbsp; <br /><br />&nbsp; &nbsp; // layout of the image&nbsp; <br />&nbsp; &nbsp; NSURL *url = [NSURL URLWithString:tw.profile_image_url];<br />&nbsp; &nbsp; NSData *data = [NSData dataWithContentsOfURL:url];<br />	cell.imageView.image = [UIImage imageWithData:data];<br />	cell.selectionStyle = UITableViewCellSelectionStyleNone;<br /><br /><br />&nbsp; &nbsp; <br />&nbsp; &nbsp; label = [[UILabel alloc] initWithFrame:CGRectZero];<br />&nbsp; &nbsp; [label setLineBreakMode:UILineBreakModeWordWrap];<br />&nbsp; &nbsp; [label setMinimumFontSize:12];<br />&nbsp; &nbsp; [label setNumberOfLines:0];<br />&nbsp; &nbsp; [label setFont:[UIFont systemFontOfSize:12]];<br />&nbsp; &nbsp; label.textColor = [UIColor blueColor];<br />&nbsp; <br />&nbsp; &nbsp; <br />&nbsp; &nbsp; [label setTag:1];<br />&nbsp; &nbsp; <br />&nbsp; &nbsp; tweet = [[UILabel alloc] initWithFrame:CGRectZero];<br />&nbsp; &nbsp;  [tweet setLineBreakMode:UILineBreakModeWordWrap];<br />&nbsp; &nbsp;  [tweet setMinimumFontSize:10];<br />&nbsp; &nbsp;  [tweet setNumberOfLines:0];<br />&nbsp; &nbsp;  <br />&nbsp; &nbsp;  <br />&nbsp; &nbsp;  [tweet setFont:[UIFont systemFontOfSize:12]];&nbsp; &nbsp; <br />&nbsp; &nbsp; <br />&nbsp; &nbsp; [[cell contentView] addSubview:label];<br />&nbsp; &nbsp; [[cell contentView] addSubview:tweet];<br /><br /><br />&nbsp; &nbsp; <br />&nbsp; &nbsp; <br />&nbsp; &nbsp; [label setText:tw.userName];<br />&nbsp; &nbsp;  [tweet setText:tw.tweetText];<br />&nbsp;  <br />&nbsp; &nbsp; [label setFrame:CGRectMake( 70, 10, 260, 10)];<br />&nbsp; &nbsp;  [tweet setFrame:CGRectMake(70, 20, 200, 60)];<br />&nbsp; <br />	<br />&nbsp; <br />&nbsp;  <br />&nbsp; &nbsp; return cell;<br />}<br /><br /><br />


merci

Réponses

  • KubernanKubernan Membre
    janvier 2012 modifié #2
    Bonjour,

    Si tu utilise Storyboard , tu peux supprimer (puisque du coup tu bénéficies de l'automatic loading cell) :

    if (cell == nil) {<br /> cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];<br /> }
    


    Ensuite il semble que tu utilises Storyboard (c.f. tes précédents messages), du coup je ne vois pas du tout l'intérêt de coder la création de tes labels.

    Enfin, l'affichage de tes données peut se faire de manière asynchrone.

    K.
  • 04:43 modifié #3
    dans 1326974404:

    Bonjour,

    Si tu compiles pour iOS 5, tu peux supprimer :

    if (cell == nil) {<br /> cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];<br /> }
    


    Ensuite il semble que tu utilises Storyboard (c.f. tes précédents messages), du coup je ne vois pas du tout l'intérêt de coder la création de tes labels.

    Enfin, l'affichage de tes données peut se faire de manière asynchrone.

    K.


    Mais oui c'est ça, c'est ça...
  • KubernanKubernan Membre
    04:43 modifié #4
    dans 1326974712:

    dans 1326974404:

    Bonjour,

    Si tu compiles pour iOS 5, tu peux supprimer :

    if (cell == nil) {<br /> cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];<br /> }
    


    Ensuite il semble que tu utilises Storyboard (c.f. tes précédents messages), du coup je ne vois pas du tout l'intérêt de coder la création de tes labels.

    Enfin, l'affichage de tes données peut se faire de manière asynchrone.

    K.


    Mais oui c'est ça, c'est ça...


    Bah oui
  • NackuNacku Membre
    04:43 modifié #5
    Ben justement, j'aurais voulu utiliser le storyboard pour positionner les éléments à  afficher dans ma cellule. Mais j'ai un vilain message d'erreur voir précédent post

    http://pommedev.mediabox.fr/utilisation-des-classes-cocoa-touch/custom-cell-tableview/

    du coup j'ai programmé ça à  la main ...

    et pour afficher ma tableview de façon asynchrone, tu peux donner quelques indices (voir de la doc) car je vois pas comment m'y prendre

    merci pour les réponses
  • KubernanKubernan Membre
    04:43 modifié #6
    dans 1326975443:

    Ben justement, j'aurais voulu utiliser le storyboard pour positionner les éléments à  afficher dans ma cellule. Mais j'ai un vilain message d'erreur voir précédent post

    http://pommedev.mediabox.fr/utilisation-des-classes-cocoa-touch/custom-cell-tableview/

    du coup j'ai programmé ça à  la main ...

    et pour afficher ma tableview de façon asynchrone, tu peux donner quelques indices (voir de la doc) car je vois pas comment m'y prendre

    merci pour les réponses


    J'ai répondu à  ton problème précédent (l'erreur est facile à  corriger).

    Tu as bien évidement le choix de tout coder à  la mimine mais ça serait dommage de s'arrêter à  la première difficulté venue :-)
    Pour l'asynchrone je te suggère d'abord de tester le résultat tel que avec un bon volume de données.

    k.
  • 04:43 modifié #7
    Ce n'est pas parce qu'il compile avec iOS 5 qu'il peut supprimer la ligne. Mais plutôt parce qu'il utilise les storyboards.
  • KubernanKubernan Membre
    04:43 modifié #8
    dans 1326978507:

    Ce n'est pas parce qu'il compile avec iOS 5 qu'il peut supprimer la ligne. Mais plutôt parce qu'il utilise les storyboards.


    Et oui c'est ça. Plutôt que de répondre de façon épidermique comme vous l'avez fait, vous auriez pu comprendre que je parlais iOS5 + Storyboard (les précédents messages de Lunack parlaient de storyboard). Je me suis simplement gouré lors d'un copier/coller.

    J'ajoute que malgré mon usage intensif de Storyboard j'obtiens des mesures d'affichage tout à  fait convenable (60 fps) sur mes tests en gros volume. Je devrai peut-être (re)coder tout en dur (on ne sait jamais je pourrai atteindre du 100 fps...). Dans la version précédente de mon soft je codais en dur pour les mêmes résultats.

    K.
  • AliGatorAliGator Membre, Modérateur
    04:43 modifié #9
    dans 1326974404:

    Si tu compiles pour iOS 5, tu peux supprimer :

    if (cell == nil) {<br /> cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];<br /> }
    
    Woooow ça m'a choqué aussi de lire ça j'en suis tombé de mon siège !

    iOS5 ne permet certainement pas de supprimer cette ligne là .
    Déjà  qu'on a plein de gens qui ne comprennent pas le principe de reuse des TableViewCells et qu'on doit leur réexpliquer à  chaque fois le principe et comment l'utiliser correctement pour optimiser la mémoire et le recyclage... Si en plus on commence à  les embrouiller...
  • 04:43 modifié #10
    Même si ça colle avec l'utilisation de Storyboard, tu devrais corriger ton post quand même, on sait jamais si des gens viennent se renseigner  ;)
    En tout cas ça confirme ma crainte.. les storyboard et ARC sont bel et bien des nouveautés pour attirer le peu de personnes qui craignaient un minimum le développement sur iOS.
  • AliGatorAliGator Membre, Modérateur
    04:43 modifié #11
    Oui Louka j'avais la même crainte et cela confirme mon avis aussi.

    C'est bien de vouloir faciliter la vie des devs, ça part d'un bon sentiment, mais on en arrive à  avoir des gens qui ne savent même plus comment ça se passe sous le capot et donc ne comprennent plus la logique des choses et comment ça marche. Du coup quand il y a un problème, vu qu'ils n'ont pas la maà®trise de ce qui se passe ils sont bloqués...

    Pour moi ARC, Storyboard & co, c'est un peu comme CoreData : c'est une techno très puissante et qui peut te faciliter la vie... mais surtout pas à  utiliser par les débutants qui n'ont pas expérimenté les bases avant. L'impression de facilité que ça donne nécessite quand même de savoir ce qui se passe un peu derrière pour déboguer, comprendre quand ça coince, ou pour mieux optimiser les choses et savoir pourquoi ça plante quand ça bug etc.
    C'est comme si on te donnais une voiture qui avec boite automatique, en général c'est plus simple à  conduire et ça marche bien, mais quand elle buget que tu passes sur boite manuelle, si t'en as jamais utilisé de ta vie t'es paumé...
  • KubernanKubernan Membre
    04:43 modifié #12
    dans 1326980918:

    Même si ça colle avec l'utilisation de Storyboard, tu devrais corriger ton post quand même, on sait jamais si des gens viennent se renseigner  ;)
    En tout cas ça confirme ma crainte.. les storyboard et ARC sont bel et bien des nouveautés pour attirer le peu de personnes qui craignaient un minimum le développement sur iOS.


    J'ai corrigé.
  • NackuNacku Membre
    janvier 2012 modifié #13


    sinon un dev m'avait fait cette remarque
    pour l'image en async avec un système de cache car là  c'est pas tres optimisé la partie cellForRowAtIndexPath

    apparemment ca ne vous a pas choqué ...
  • AliGatorAliGator Membre, Modérateur
    04:43 modifié #14
    Heu tu peux remettre dans le contexte pour ta citation ?

    Car oui dans le cadre d'une TableView si tu veux y afficher des images venant du net il faut les charger en asynchrone pour pas bloquer le main thread. Et oui il faut utiliser un système de cache pour éviter d'envoyer une requête à  chaque fois que tu scroll ta tableview et réaffiche une cell dont l'image aurait déjà  été chargée.
    Je vois pas ce qu'il y aurait de choquant du moins de ce que je lis à  première vue. Ca me parait même sensé.
  • KubernanKubernan Membre
    04:43 modifié #15
    dans 1326982789:



    sinon un dev m'avait fait cette remarque
    pour l'image en async avec un système de cache car là  c'est pas tres optimisé la partie cellForRowAtIndexPath

    apparemment ca ne vous a pas choqué ...


    On reprend tranquillement. Suite à  une erreur de typo les foudres me sont tombées dessus. Ce que je comprends. J'ai corrigé.
    Pour ton code j'ai supposé (rapport à  tes messages précédents) que tu utilisais encore Storyboard.

    Si tu tiens à  tout coder, tu noteras que dans ton code, même si tu réutilise une cell tu recréé systématiquement les éléments de la cell...
    L'idée est plutôt :

    if (cell == nil) {
        setup de la cell et de ses éléments
    }
    // Configurer la cell
  • NackuNacku Membre
    04:43 modifié #16
    dans 1326984265:

    Heu tu peux remettre dans le contexte pour ta citation ?

    Car oui dans le cadre d'une TableView si tu veux y afficher des images venant du net il faut les charger en asynchrone pour pas bloquer le main thread. Et oui il faut utiliser un système de cache pour éviter d'envoyer une requête à  chaque fois que tu scroll ta tableview et réaffiche une cell dont l'image aurait déjà  été chargée.
    Je vois pas ce qu'il y aurait de choquant du moins de ce que je lis à  première vue. Ca me parait même sensé.


    En fait il m'avait dit de récupérer et traiter mon json de manière asynchrone. Et il avait fait la meme remarque pour le tableview pour l'image.

    sur le site d'apple, j'ai trouvé un exemple lazzytableImages

    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath<br />{<br />	// customize the appearance of table view cells<br />	//<br />	static NSString *CellIdentifier = @&quot;LazyTableCell&quot;;<br />&nbsp; &nbsp; static NSString *PlaceholderCellIdentifier = @&quot;PlaceholderCell&quot;;<br />&nbsp; &nbsp; <br />&nbsp; &nbsp; // add a placeholder cell while waiting on table data<br />&nbsp; &nbsp; int nodeCount = [self.entries count];<br />	<br />	if (nodeCount == 0 &amp;&amp; indexPath.row == 0)<br />	{<br />&nbsp; &nbsp; &nbsp; &nbsp; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:PlaceholderCellIdentifier];<br />&nbsp; &nbsp; &nbsp; &nbsp; if (cell == nil)<br />		{<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle<br />										&nbsp;  reuseIdentifier:PlaceholderCellIdentifier] autorelease];&nbsp;  <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; cell.detailTextLabel.textAlignment = UITextAlignmentCenter;<br />			cell.selectionStyle = UITableViewCellSelectionStyleNone;<br />&nbsp; &nbsp; &nbsp; &nbsp; }<br /><br />		cell.detailTextLabel.text = @&quot;Loading...&quot;;<br />		<br />		return cell;<br />&nbsp; &nbsp; }<br />	<br />&nbsp; &nbsp; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];<br />&nbsp; &nbsp; if (cell == nil)<br />	{<br />&nbsp; &nbsp; &nbsp; &nbsp; cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle<br />									&nbsp;  reuseIdentifier:CellIdentifier] autorelease];<br />		cell.selectionStyle = UITableViewCellSelectionStyleNone;<br />&nbsp; &nbsp; }<br /><br />&nbsp; &nbsp; // Leave cells empty if there&#039;s no data yet<br />&nbsp; &nbsp; if (nodeCount &gt; 0)<br />	{<br />&nbsp; &nbsp; &nbsp; &nbsp; // Set up the cell...<br />&nbsp; &nbsp; &nbsp; &nbsp; AppRecord *appRecord = [self.entries objectAtIndex:indexPath.row];<br />&nbsp; &nbsp; &nbsp; &nbsp; <br />		cell.textLabel.text = appRecord.appName;<br />&nbsp; &nbsp; &nbsp; &nbsp; cell.detailTextLabel.text = appRecord.artist;<br />		<br />&nbsp; &nbsp; &nbsp; &nbsp; // Only load cached images; defer new downloads until scrolling ends<br />&nbsp; &nbsp; &nbsp; &nbsp; if (!appRecord.appIcon)<br />&nbsp; &nbsp; &nbsp; &nbsp; {<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (self.tableView.dragging == NO &amp;&amp; self.tableView.decelerating == NO)<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; [self startIconDownload:appRecord forIndexPath:indexPath];<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // if a download is deferred or in progress, return a placeholder image<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; cell.imageView.image = [UIImage imageNamed:@&quot;Placeholder.png&quot;];&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />&nbsp; &nbsp; &nbsp; &nbsp; }<br />&nbsp; &nbsp; &nbsp; &nbsp; else<br />&nbsp; &nbsp; &nbsp; &nbsp; {<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;  cell.imageView.image = appRecord.appIcon;<br />&nbsp; &nbsp; &nbsp; &nbsp; }<br /><br />&nbsp; &nbsp; }<br />&nbsp; &nbsp; <br />&nbsp; &nbsp; return cell;<br />}<br /><br />
    


    c'est le bon exemple ? c'est gérer de façon asynchrone ?

    merci à  tous pour vos remarques
  • KubernanKubernan Membre
    04:43 modifié #17
    dans 1326985161:

    dans 1326984265:

    Heu tu peux remettre dans le contexte pour ta citation ?

    Car oui dans le cadre d'une TableView si tu veux y afficher des images venant du net il faut les charger en asynchrone pour pas bloquer le main thread. Et oui il faut utiliser un système de cache pour éviter d'envoyer une requête à  chaque fois que tu scroll ta tableview et réaffiche une cell dont l'image aurait déjà  été chargée.
    Je vois pas ce qu'il y aurait de choquant du moins de ce que je lis à  première vue. Ca me parait même sensé.


    En fait il m'avait dit de récupérer et traiter mon json de manière asynchrone. Et il avait fait la meme remarque pour le tableview pour l'image.

    sur le site d'apple, j'ai trouvé un exemple lazzytableImages

    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath<br />{<br />	// customize the appearance of table view cells<br />	//<br />	static NSString *CellIdentifier = @&quot;LazyTableCell&quot;;<br />&nbsp; &nbsp; static NSString *PlaceholderCellIdentifier = @&quot;PlaceholderCell&quot;;<br />&nbsp; &nbsp; <br />&nbsp; &nbsp; // add a placeholder cell while waiting on table data<br />&nbsp; &nbsp; int nodeCount = [self.entries count];<br />	<br />	if (nodeCount == 0 &amp;&amp; indexPath.row == 0)<br />	{<br />&nbsp; &nbsp; &nbsp; &nbsp; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:PlaceholderCellIdentifier];<br />&nbsp; &nbsp; &nbsp; &nbsp; if (cell == nil)<br />		{<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle<br />										&nbsp;  reuseIdentifier:PlaceholderCellIdentifier] autorelease];&nbsp;  <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; cell.detailTextLabel.textAlignment = UITextAlignmentCenter;<br />			cell.selectionStyle = UITableViewCellSelectionStyleNone;<br />&nbsp; &nbsp; &nbsp; &nbsp; }<br /><br />		cell.detailTextLabel.text = @&quot;Loading...&quot;;<br />		<br />		return cell;<br />&nbsp; &nbsp; }<br />	<br />&nbsp; &nbsp; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];<br />&nbsp; &nbsp; if (cell == nil)<br />	{<br />&nbsp; &nbsp; &nbsp; &nbsp; cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle<br />									&nbsp;  reuseIdentifier:CellIdentifier] autorelease];<br />		cell.selectionStyle = UITableViewCellSelectionStyleNone;<br />&nbsp; &nbsp; }<br /><br />&nbsp; &nbsp; // Leave cells empty if there&#039;s no data yet<br />&nbsp; &nbsp; if (nodeCount &gt; 0)<br />	{<br />&nbsp; &nbsp; &nbsp; &nbsp; // Set up the cell...<br />&nbsp; &nbsp; &nbsp; &nbsp; AppRecord *appRecord = [self.entries objectAtIndex:indexPath.row];<br />&nbsp; &nbsp; &nbsp; &nbsp; <br />		cell.textLabel.text = appRecord.appName;<br />&nbsp; &nbsp; &nbsp; &nbsp; cell.detailTextLabel.text = appRecord.artist;<br />		<br />&nbsp; &nbsp; &nbsp; &nbsp; // Only load cached images; defer new downloads until scrolling ends<br />&nbsp; &nbsp; &nbsp; &nbsp; if (!appRecord.appIcon)<br />&nbsp; &nbsp; &nbsp; &nbsp; {<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (self.tableView.dragging == NO &amp;&amp; self.tableView.decelerating == NO)<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; [self startIconDownload:appRecord forIndexPath:indexPath];<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // if a download is deferred or in progress, return a placeholder image<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; cell.imageView.image = [UIImage imageNamed:@&quot;Placeholder.png&quot;];&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />&nbsp; &nbsp; &nbsp; &nbsp; }<br />&nbsp; &nbsp; &nbsp; &nbsp; else<br />&nbsp; &nbsp; &nbsp; &nbsp; {<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;  cell.imageView.image = appRecord.appIcon;<br />&nbsp; &nbsp; &nbsp; &nbsp; }<br /><br />&nbsp; &nbsp; }<br />&nbsp; &nbsp; <br />&nbsp; &nbsp; return cell;<br />}<br /><br />
    


    c'est le bon exemple ? c'est gérer de façon asynchrone ?

    merci à  tous pour vos remarques


    L'exemple que tu donnes se résume ainsi : je ne bloque pas l'application pendant que je récupère les données (que du texte apparemment), je charge ensuite les images quand j'en ai besoin. C'est plutôt pas mal...
    Tu auras compris qu'ici ce n'est pas le cellForRowAtIndexPath: qui fait tout : la source de donnée est ici "entries", elle est alimentée ailleurs et sûrement en asynchrone.
    K.
  • NackuNacku Membre
    04:43 modifié #18
    et si je fais une fonction loadimage avec callback didreceiveData, didreceiveReponse, connectionDidFinishLaunching ! ca serait du assynchrone ? comme ça ?
  • jojolebgjojolebg Membre
    février 2012 modifié #19
    Bonjour,



    sur l'exemple que tu donnes il y a, je pense, certaines choses qu'il ne faut pas faire:


    <br />
    - (UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {<br />
    <br />
      static NSString *CellIdentifier = @&quot;CellIdentifier&quot;;<br />
      Tweet *tw = [listdata objectAtIndex:indexPath.row];<br />
      UILabel *label;<br />
      UILabel *tweet;<br />
    	<br />
      UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];<br />
      if (cell == nil)<br />
    	// Creation de la cell<br />
    	cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];<br />
      }<br />
    <br />
      ...<br />
      // Créations les Labels<br />
      label = [[UILabel alloc] initWithFrame:CGRectZero];<br />
      ...<br />
      // Ajout des labels à  la cellule<br />
      [[cell contentView] addSubview:label];<br />
      ...<br />
      // Configuration des labels<br />
      [label setText:tw.userName];<br />
      ...<br />
      <br />
      return cell;<br />
    }<br />
    




    Il serait plus judicieux de mettre les parties "Créations des labels" et "Ajout des labels à  la cellule" juste en dessous de la partie "Creation de la cell" (à  l'interieur du IF)

    En effet, à  chaque fois qu'une de tes cellules sera cachée puis réaffichée (en scrollant la tableView par exemple), la methode cellForRowAtIndexPath sera appeler. La premiere fois tout se passera bien, la cellule sera créée, les labels créés, et les labels ajoutés dans la cellule. La deuxième fois par contre, grace à  la ligne [tableView dequeueReusableCellWithIdentifier:CellIdentifier] on récupère une cellule déjà  configurée (contenant déjà  les labels), puis on créer des labels et on les rajoutes à  la cellule (ta cellule contiendra plusieurs fois les meme labels). Et ainsi de suite.



    Si ta cellule sort 10 fois de l'écran, ta cellule contiendra 10 labels différents.



    (PS: pourquoi j'ai l'impression que sur le code source des sauts lignes sont ajoutés automatiquement ?)
  • AliGatorAliGator Membre, Modérateur
    Je confirme ce que dit jojolebg, tu n'utilises pas correctement le recyclage des cellules, et ça c'est une horreur.

    Parce que les perfs sont dégradées, et parce que tu vas recréer plein de fois tout ton contenu, label, etc, sur chaque cellule recyclée, donc dès que tu vas scroller. Au bout de 2-3 scrolls intensifs tu vas te retrouver avec des cellules avec 50 labels superposés (dont tu ne te serviras que du dernier... au risque que les autres en plus de ne pas être recyclés et réutilisés gardent les valeurs avant leur recyclage)



    Bref, le truc à  éviter.

    Après si avec Storyboard c'est géré autrement ça je sais pas je l'ai jamais utilisé, mais je vois pas pourquoi, vu que le recyclage des cellules d'une TableView est un élément clé qui permet justement d'avoir des perfs correctes lors du scrolling rapide d'une TableView (je pense que StoryBoard charge ses cellules depuis un modèle, un peu comme quand on change des UITableViewCells d'un XIB (qd on travaille sans StoryBoard). Bah ça change pas le pb pour autant, le chargement de la cellule via un modèle ne la charge et ne la configure qu'une seule fois, plutôt que s'embêter à  créer son contenu et le configurer à  chaque recyclage, ce qui tuerai les perfs.
Connectez-vous ou Inscrivez-vous pour répondre.