2010-10-09 5 views
4

Je travaille sur un projet iOS de lecteur de flux. Les entrées de flux sont répertoriées dans un UITableView dans l'ordre chronologique inverse. Au lancement, ils sont chargés à partir d'une base de données dans un tableau. Lorsque l'application se synchronise sur les flux, elle crée un nouveau tableau pour le nouvel ordre de choses, puis pour mettre à jour la table, compare le nouveau tableau à l'ancien tableau pour déterminer les cellules à supprimer, mettre à jour ou insérer. La façon dont je l'ai fait est naïf, et donc vraiment inefficace: Beaucoup d'appels à indexOfObject: pour voir si un élément dans un tableau est dans l'autre tableau. Deux fois. une fois pour chaque nouvelle entrée car il est ajouté au nouveau tableau, pour voir si elle est dans l'ancien tableau, puis une fois pour chaque entrée dans l'ancien tableau, pour voir si elle est pas dans le nouveau tableau.Modèle de mise à jour de UITableView sur Sync?

En tant que professionnel de la base de données, cette conception me choque.

Mais ce doit être un modèle assez commun. Quelle serait la manière la plus appropriée et la plus adéquate de faire du cacao?

Répondre

4

Il s'avère que je venais à tort. La solution que j'ai trouvée consistait à ajouter et supprimer des éléments du tableau comme d'habitude, puis à appeler insertRowsAtIndexPaths:withRowAnimation:, reloadRowsAtIndexPaths:withRowAnimation: et deleteRowsAtIndexPaths:withRowAnimation: comme approprié pour chaque ligne ajoutée, modifiée ou déplacée. La faute dans mon plan précédent était la pensée que je devrais attendre jusqu'à ce que tous les changements et aient été faits, puis n'appelez chacune de ces méthodes qu'une seule fois dans un bloc beginUpdates/endUpdates. Il s'avère que le bloc n'était pas réellement nécessaire, car les méthodes de modification peuvent être appelées en dehors d'eux.

Il était beaucoup plus facile d'appeler chaque méthode une fois pour chaque cellule insérée, mise à jour ou supprimée, que de calculer toutes les modifications à la fin et de les valider immédiatement. Était juste trop confus, sujettes aux erreurs, et inefficace pour essayer de le faire tout à la fois.

Ainsi, le code, je fini avec ressemble à ceci:

if (parsedItem.savedState == ItemModelSavedStateInserted) { 
    // It's a new entry. Insert it. 
    [items addObject:parsedItem]; 
    [self.tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:[NSIndexPath indexPathForRow:items.count - 1 inSection:0]] withRowAnimation:UITableViewRowAnimationTop]; 
} else { 
    // It's an existing entry. Find it in the portal and move it, if necessary. 
    NSUInteger foundAt = [items 
     indexOfObject:parsedItem 
       inRange:NSMakeRange(currentItemIndex, items.count - currentItemIndex - 1) 
    ]; 
    if (foundAt == currentItemIndex) { 
     // It hasn't moved! 
     if (parsedItem.savedState == ItemModelSavedStateUpdated) { 
      // It was updated, so replace it. 
      [items replaceObjectAtIndex:currentItemIndex withObject:parsedItem]; 
      [self.tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:[NSIndexPath indexPathForRow:currentItemIndex inSection:0]] withRowAnimation:UITableViewRowAnimationMiddle]; 
     } 
    } else { 
     // It has shifted position. 
     if (foundAt != NSNotFound) { 
      // It has moved. 
      [items removeObjectAtIndex:foundAt]; 
      [self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:[NSIndexPath indexPathForRow:foundAt inSection:0]] withRowAnimation:UITableViewRowAnimationBottom]; 
     } 
     // Need to insert it. 
     [items insertObject:parsedItem atIndex:currentItemIndex]; 
     [self.tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:[NSIndexPath indexPathForRow:currentItemIndex inSection:0]] withRowAnimation:UITableViewRowAnimationTop]; 
    } 
} 
1

Pensez à utiliser NSSets pour différencier l'ensemble des éléments actuels et l'ensemble des nouveaux éléments, avec un seul NSMutableArray de tenir la liste actuelle ordonnée. Vous voudrez probablement supprimer chacun des éléments expirés du tableau, puis insérez chacun des nouveaux éléments non expirés dans le tableau. Les éléments dont vous n'avez pas besoin pour supprimer ou insérer sont les éléments que vous souhaitez mettre à jour.

Questions connexes