samedi 10 mars 2012

Cellules Voir tableau Redux

Il ya assez longtemps, j'ai posté au sujet Méthode recommandée par Apple de faire usage des cellules de tableau dans Interface Builder. Le code de ce poste a été disponible pendant 9 mois et aujourd'hui, pour la première fois, quelqu'un m'a fait remarquer que le projet ci-jointe ne pas réutiliser les cellules dequeued parce que j'ai oublié de taper l'identifiant de la cellule dans Interface Builder.

Quelle est la faiblesse de l'approche recommandée Apple. C'est un véritable talon d'Achille. C'est vraiment, vraiment facile d'oublier cette étape, et le code fonctionne parfaitement bien si vous ne l'oubliez, vous êtes juste de manger la mémoire et les performances deviennent plus pauvres que vous devriez. Sauf si vous le profil de vos applications ou de test avec des ensembles de données très volumineux, vous pourriez très bien expédier votre app de ce genre et même pas s'en rendre compte. Vous ne voulez jamais à vos clients de découvrir ces choses avant vous.

Maintenant, je ne savais même pas que j'avais fait cette erreur jusqu'à aujourd'hui, mais j'ai su que c'était un problème potentiel pour un certain temps, ce qui explique pourquoi, dans mon contrat de travail, j'ai commencé à utiliser une version modifiée du technique. Mon erreur précédemment donne-moi maintenant une bonne excuse pour après cette modification.

Surtout, c'est la même technique que j'ai discuté avant, seulement je commence par définir une constante pour l'identifiant. En fait, j'ai créer un fichier en-tête dans mes projets Xcode ConstantsAndMacros.h dans mon projet, qui je ajouter à mon fichier d'entête pré-compilés. Cela signifie que toutes les constantes et les macros j'ai mis dans ConstantsAndMacros.h sera disponible pour tous mes fichiers de code source dans mon projet sans avoir à les importer manuellement. Pour un projet simple, ce fichier pourrait ressembler à ceci:


#define TABLE_CELL_IDENTIFIER @"Table Cell Identifier"
#define NSStubLog() NSLog(@"%s", __PRETTY_FUNCTION__)^1

Une fois que j'ai ce fichier, je l'ajouter au fichier. Pch dans le Autres sources folder:

#ifdef __OBJC__
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#import "ConstantsAndMacros.h"
#endif

Maintenant que constante est disponible vaste projet ^ 2. Ensuite, dans mon sous-classe UITableViewCell, je substituer la méthode reuseIdentifier et ajouter une méthode de classe avec le même nom, comme ceci:

+ (NSString *)reuseIdentifier
{
return (NSString *)TABLE_CELL_IDENTIFIER;
}

- (NSString *)reuseIdentifier
{
return [[self class] reuseIdentifier];
}

En faisant cela, le système va ignorer tout identifiant j'ai mis dans Interface Builder, ou tout autre valeur que j'ai mis dans le code en utilisant les setBundleIdentifier: méthode mutateur. Pour les instances de cette classe particulière, il sera toujours utiliser le même identifiant. En créant la méthode de classe, j'ai accès à cet identifiant, même si je ne dispose pas encore d'une instance de la classe.

Pour toutes les autres étapes de l'aide personnalisée de cellules de tableau chargé à partir d'une plume, le processus est le même que le didacticiel précédent et il fonctionne très bien. Voici un exemple de tableView: cellForRowAtIndexPath: méthode utilisant cette technique:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{
TestCell *cell = (TestCell *)[tableView dequeueReusableCellWithIdentifier:[TestCell reuseIdentifier]];
if (cell == nil)
{
NSLog(@"Loading new cell");
[[NSBundle mainBundle] loadNibNamed:@"TestCell" owner:self options:nil];
cell = loadCell;
self.loadCell = nil;
}

cell.cellLabel.text = [NSString stringWithFormat:@"Row %d", [indexPath row]];
return cell;
}

Notez le NSLog () déclaration? Je peux ouvrir ma cellule de tableau dans Interface Builder et mettre tout identifiant que je veux, ou un ensemble pas d'identifiant à tous, et il sera toujours ré-utiliser des cellules de tableau. Exécuter l'application, et peu importe ce que vous faites dans Interface Builder, vous ne verrez une poignée de lignes chargées à partir du fichier nib. Après le chargement initial, il va tout simplement continuer de réutiliser les instances même cellule à plusieurs reprises. Ce qui est loin moins fragiles que d'avoir à s'assurer que l'identifiant de l'IB et celui de votre match de code.

Il pourrait y avoir des moments où vous ne voulez pas l'installer comme ça - quand vous avez besoin d'avoir plusieurs identifiants pour la classe d'affichage d'une même table, mais ces situations seront extrêmement rares. Dans la plupart des situations pratiques où vous êtes sous-classes UITableViewCell, vous voulez un identifiant unique pour toutes les instances de cette classe. Ce que vous ne voulez normalement est la fragilité d'avoir à vous assurer de la valeur dans votre code correspond à celle de IB exactement, surtout étant donné qu'il n'y a aucun signe évident que vous avez oublié de le faire.


1 Cette macro journaux juste le nom de la méthode de la fonction qu'il est placé dans lorsque cette méthode est appelée. Je l'utilise chaque fois que je bouchonner une méthode pour s'assurer IBAction mes connexions sont toutes faites correctement, d'où le nom, mais c'est utile pour le débogage ainsi.

2 Si vous utilisez uniquement une cellule de tableau dans un seul contrôleur, vous n'avez probablement pas le voulez ici. En général, j'essaie de créer des cellules de tableau pour être suffisamment générique pour être utilisé dans plus d'un contrôleur. Parfois, ce n'est pas possible ou pratique, et dans ces cas, # define votre identifiant dans l'en-tête du contrôleur de table tenu à la place.

Vous pouvez trouver un projet de mise en œuvre de l'échantillon ici/

Aucun commentaire: