Comment puis-je accélérer un UITableView?
J'ai un UITableView avec environ 400 cellules dans 200 articles et c'est un peu lent dans la réponse à l'interaction utilisateur (défilement, la sélection de cellules.) J'ai assuré les méthodes de récupération des cellules d'en-tête et les vues de faire le strict minimum, comme c'est la course, et je ne pense pas que je suis en train de faire quelque chose hors de l'ordinaire pour le faire ralentir. Les cellules et les en-têtes juste une image d'arrière-plan et de texte. Quelqu'un d'autre a eu ce genre de problème, et connaissez-vous un moyen de le rendre un peu plus vite?
Edit: je suis en offrant une prime parce que j'aimerais obtenir quelques commentaires utiles sur ce. Je ne pas pense que la réponse réside dans un problème dans mon code. Au lieu de cela je suis à la recherche de stratégies de re-conception de la UITableView de sorte qu'il s'exécute plus rapidement. Je suis totalement ouvert à l'ajout d'un nouveau code et j'ai hâte d'entendre ce que vous les gars ont à dire.
Lenteur est observée sur les deux le simulateur et mon appareil, un iPhone 4. Voici mes implémentations de viewForHeaderInSection
et cellForRowAtIndexPath
, qui sont les seuls UITableViewDelegate
les méthodes de mise en œuvre nontrivially. Je suis la réutilisation des cellules d'en-tête et points de vue.
- (UIView*)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger) section
{
HaikuHeaderView* view= [m_sectionViews objectAtIndex:section];
NSMutableArray* array= [m_haikuSearch objectAtIndex:section];
Haiku* haiku= [array objectAtIndex:0];
[view.poetLabel setText:[haiku nameForDisplay]];
return view;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease];
cell.backgroundView= [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"cell gradient2.png"]];
//(Set up a bunch of label attributes in the cell...)
}
NSMutableArray* array= [m_haikuSearch objectAtIndex:indexPath.section];
Haiku* haiku = [array objectAtIndex:indexPath.row];
cell.textLabel.text = [haiku.m_lines objectAtIndex:0];
return cell;
}
- il serait utile si vous pouviez nous montrer comment vous avez mis en œuvre ces méthodes. Pas tout le code, mais juste de la logique de base
- Quels sont les dispositifs que vous tester sur? Ou est la lenteur également observées sur votre Mac?
- Voir ma réponse à cette question, je donne beaucoup de détails sur l'optimisation de votre code pour tableviews. HTH
- Double Possible qui répond à votre question: Astuces pour améliorer iPhone UITableView les performances de défilement?
- comment au sujet de la lecture de l'image une fois à partir d'un fichier n en utilisant cet objet au lieu de lire à partir d'un fichier de tous les temps.... [UIImage imageNamed:@"cellule gradient2.png"]];
Vous devez vous connecter pour publier un commentaire.
Même si votre portable est en fait que de simples (image d'arrière-plan et de l'étiquette) il y a quelques choses à considérer
Cache d'Image
C'est la chose la plus évidente - si vous utilisez la même image partout, de le charger une fois dans le UIImage et de le réutiliser. Même si le système de cache sur son propre, directement à l'aide de la déjà chargé, on ne doit jamais faire mal.
Calcul rapide
Une autre chose la plus évidente - faire le calcul de la hauteur et le contenu aussi vite que possible. Ne faites pas synchrone extrait (appels réseau, la lecture du disque, etc.).
Canal Alpha de l'image
Ce qui est cher quand le dessin est à la transparence. Que votre arrière-plan de cellule a rien derrière elle, assurez-vous d'enregistrer votre image sans canal alpha. Cela permet d'économiser beaucoup de traitement.
Étiquette transparente
La même chose vaut pour l'étiquette sur le dessus de votre arrière-plan de la vue, malheureusement, le rendant opaque peut ruiner l'apparence de votre cellule, mais cela dépend de l'image.
De cellule personnalisé
En général, les sous-classement
UITableViewCell
et la mise en œuvre dedrawRect:
vous-même est plus rapide que la construction de la sous-vue de la hiérarchie. Vous pourriez faire de votre image une variable de classe que tous les cas d'utilisation. DansdrawRect:
vous avais dessiner l'image et le texte sur le dessus de cela.Vérifier la composition
Le simulateur est un outil pour mettre en évidence les points qui sont rendu cher à cause de la transparence (le vert est ok, le rouge est en alpha-blending). Il peut être trouvé dans le menu déboguer: "Couleur Mélangée Couches"
La meilleure chose que vous pouvez faire si vous êtes à la recherche pour accélérer votre code est de profil. Il y a deux raisons à cela:
Vous pouvez lire à propos de certaines choses qui vont améliorer les performances de la table en général, comme l'utilisation de hauteur fixe de cellules et de ré-utiliser les cellules, et il sera probablement aider à mettre en œuvre ces choses (on dirait que vous avez déjà fait). Mais quand il s'agit de l'accélération votre code, vous avez vraiment besoin de savoir où vous app est de passer la plupart de son temps. Il se pourrait qu'il existe quelques méthodes qui prennent un temps très long, ou une méthode relativement rapide, mais est appelé à une beaucoup plus souvent que vous le souhaitez.
Il est impossible de savoir si les changements que vous faites dans un effort pour accélérer les choses vraiment faire une différence, sauf si vous avez quelques chiffres pour mesurer contre. Si vous pouvez prouver que votre code a été de dépenser 80% de son temps dans une routine et vous coupez que jusqu'à 35%, vous savez que vous avez fait des progrès.
Donc, de briser les Instruments et de commencer à mesurer. Si vous le pouvez, il est une bonne idée de mesurer pendant que vous êtes en train de faire chacune des différentes activités que vous souhaitez accélérer... faire une session de profilage pendant le défilement, tout en choisissant le nombre de cellules différentes que vous pouvez dans un délai fixe, etc. N'oubliez pas d'enregistrer les résultats de sorte que vous pouvez comparer plus tard.
Il suffit de noter ces points..
une bonne pratique de le faire..
cher calculs dans
cellForRowAtIndexPath de rappel, ou
dans un appel de fonction de
CellForRowAtIndexPath..
image. Une autre raison pour laquelle vous devez
la réutilisation de votre cellule.
Quelques bonnes infos sur la cellule de réutilisation est ici..
EDIT : Trouvé cette page très fin..
Ce DONC, la question thread peut vous aider...surtout la accepté de répondre...
utilisation de l'image partagée exemple pour le fond (vous alloc/init/version un pour chaque fois une nouvelle cellule est créée). Lorsque votre vue de la table est grande , cela signifie que le fond de X cellules dans la mémoire prend beaucoup plus de mémoire qu'il ne le devrait.
au lieu de
cell.backgroundView= [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"cell gradient2.png"]];
utilisez simplement :
cell.backgroundView= [SomeHelperClass sharedBackgroundUIImageResource];
Si cela ne fonctionne pas , l'utilisation de la CG au lieu d'étiquettes et d'autres sous-vues (une capture d'écran de l'aide ici.. pour savoir de quoi nous parlons).
La table de la vue du délégué mettre en œuvre:
Si donc vous souhaitez peut-être envisager de mettre votre UITableViewCell de rowHeight propriété plutôt.
tableView.estimatedRowHeight
pourrait aider un peu. Pour moi, il semble rendre un peu plus rapide, mais le défilement est encore très instable.Utilisez-vous beaucoup de sous-vues?
Si oui, une bonne technique est d', au lieu d'ajouter un grand nombre d'étiquettes et les images, de les dessiner à l'aide de CoreGraphics.
Pour ce faire, vous devez avoir une classe de UITableViewCell et de mettre en œuvre la
-(void)drawRect:(CGRect)rect
méthode.Deux propositions: l'Une consiste à utiliser
-initWithStyle:reuseIdentifier:
pour votre table de visualiser les cellules au lieu de initWithFrame:. L'autre est de commenter le réglage de la cellule.backgroundView à une image avec un dégradé et voir si c'est le coupable. Chaque fois que j'ai eu de mauvaises performances dans un affichage tableau, c'est à cause d'une image.C'est un peu hors-sujet ici (parce que vous avez seulement une image d'arrière-plan pour toutes les cellules):
Mon application affiche des images différentes dans chaque cellule. Après l'ajout d'environ 5 cellules de UITableView - table est ralentie considérablement. Il faut environ 1 à 2 secondes pour traiter toutes les images chaque fois que j'ouvre la vue du contrôleur.
J'ai donc fini à la production de petites VIGNETTES pour toutes mes images.
La réutilisation des cellules. Allocation des objets a un coût, surtout si l'allocation doit se produire à plusieurs reprises sur une courte période—dire, lorsque l'utilisateur fait défiler la vue de la table. Si vous réutilisez des cellules au lieu d'allouer de nouvelles, vous améliorer grandement la table vue de la performance.
Éviter la nouvelle disposition de contenu. En cas de réutilisation de cellules personnalisée avec des sous-vues, de s'abstenir de disposer ces sous-vues à chaque fois que l'affichage de la table demande une cellule. Posez les sous-vues une fois, lorsque la cellule est créée.
L'utilisation opaque sous-vues. Lors de la personnalisation de la vue tableau de cellules, de faire de la sous-vues de la cellule opaque, pas transparent.