2009-05-05 11 views
3

Consultez les dernières lignes avant [cellule de retour] .. Une fois que les images sont chargées de la vitesse de défilement est decreasing..it semble que le défilement se coinceComment augmenter la vitesse du défilement dans la vue de table lorsque des images sont chargées dans chaque cellule?

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 

    static NSString *MyIdentifier = @"MyIdentifier"; 
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:MyIdentifier]; 

    if (cell == nil) { 
     cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:MyIdentifier] autorelease]; 
    } 

    int storyIndex = [indexPath indexAtPosition: [indexPath length] - 1]; 
    NSString *itemDescription=[[stories objectAtIndex: storyIndex] 
               objectForKey:@"title"]; 

    CGRect aframe = CGRectMake(80, 30, 250, 40); 
    textLabel = [[UILabel alloc] initWithFrame:aframe]; 
     textLabel.font = [UIFont boldSystemFontOfSize:14]; 
    textLabel.numberOfLines=0; 
    textLabel.textColor = [UIColor darkTextColor]; 
    textLabel.backgroundColor = [UIColor whiteColor]; 
    [cell.contentView addSubview:textLabel]; 
    textLabel.text=itemDescription; 

    CGRect frame = CGRectMake(0, 0, 70,80); 
    UIImageView *TopImageView = [[UIImageView alloc] init]; 
    [cell.contentView addSubview:TopImageView]; 
    TopImageView.frame=frame; 

    m_strImage = [m_imglinkArray objectAtIndex:storyIndex]; 

    TopImage = [[UIImage alloc] initWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:m_strImage]]]; 
    TopImageView.image=TopImage; 

    return cell; 
} 

Pourriez-vous les gars me aider à augmenter la vitesse de le parchemin?

Cordialement

Arun

+0

vous devez améliorer la mise en forme de vous remettre en question parce que son pas lisible ... –

Répondre

0

Il semble que vous chargez d'une URL à chaque fois que la vue de la table demande pour obtenir la cellule pour une ligne. Cela se produit dans le thread d'application principal (le thread d'interface utilisateur) et il bloque l'interface utilisateur, le rendant non réactif.

Surtout si cette URL est une ressource que vous chargez sur Internet, cette pause est importante.

Je vous recommande de charger les images dans un fil d'arrière-plan et d'afficher une image d'espace réservé jusqu'à ce qu'elles soient extraites du réseau.

Vous pouvez essayer la solution proposée dans l'adresse suivante ...

http://www.markj.net/iphone-asynchronous-table-image/

2

Je crois que vous pouvez avoir deux problèmes ici. La première est le problème de ne pas multi-threader les charges d'image et la seconde est comment vous utilisez UITableViewCell.

L'iPhone appelle cellForRowAtIndexPath chaque fois qu'une cellule apparaît à l'écran - si vous faites défiler vers le bas, tout ce qui précède est déchargé et rechargé lorsque vous faites défiler vers le haut à nouveau. Comme déjà noté, ceci peut être résolu avec des patterns multithread - soit le lien posté sur markj.net, et/ou en utilisant NSThread. L'avantage de NSThread est que vous avez plus de flexibilité pour gérer les problèmes ou charger plus que des données d'image. (J'utiliserais les deux)

Pour ce faire efficacement, vous devez avoir un UITableViewCell personnalisé. C'est bien d'avoir quoi que ce soit parce que vous pouvez rendre la cellule du tableau responsable de son contenu plutôt que de votre contrôleur de vue, et vous pouvez manipuler efficacement la mise en forme et le contenu des cellules. Voici un lien vers un grand post sur UITableCellView: http://blog.atrexis.com/index.cfm/2009/1/6/iPhone--Customize-the-UITableCellView

Lorsque vous implémentez UITableViewCell, faites de votre mieux pour mettre tous les appels addSubview et mise en forme dans le « if (cellule == nil) » bloc, seulement si vous ne pouvez pas les mettre dans votre initWithFrame personnalisé. Vous verrez que l'iPhone empile toutes les sous-vues que vous ajoutez - cela ne supprime pas l'ancienne vue. Vous pouvez le voir au travail en réglant toutes les couleurs d'arrière-plan sur "UIColor clearColor", puis en changeant le texte entre les occurrences - vous verrez une pile de texte les unes sur les autres. Ceci n'est normalement pas visible car les arrière-plans pleins dessinent sur toutes les "anciennes" sous-vues.

Avant de combiner ces deux méthodes, pensez à implémenter un "modèle". Vous avez une vue et un contrôleur mais toutes vos données doivent être dans un modèle. Toutes les URL d'image, le contenu, etc. doivent être dans quelque chose comme un NSMutableArray, un objet personnalisé de votre choix, ou peut-être via SQLite. Une fois que vous avez un modèle, vous pouvez implémenter votre mise en cache des images. Avec la mise en cache, toutes les images seront conservées entre les charges de votre application, ce qui permettra d'économiser les piles, la bande passante et le temps.

Je voudrais: 1. Mettez toutes vos données dans un modèle quelconque (NSMutableArray, SqlLite, quelque chose) 2.Mettre en œuvre votre propre UITableViewCell personnalisée 3. Assurez-vous que vous avez 0 addSubview, init, ou des appels alloc à l'intérieur du bloc actif de cellForRowAtIndexPath 4. Utilisez exemple de délégation ou NSThread pour charger toutes les images en arrière-plan 5. Ajouter la mise en cache d'image locale

Il existe de bons exemples sur et sur les forums Apple sur la mise en cache des images.

2

nessence a beaucoup de bonnes informations. Quelques pensées de plus:

Vous fuyez comme un fou ici. Chaque cellule que vous créez, vous fuire 2 UILabels, un UIImageView et un UIImage.

Comme indiqué précédemment, non seulement vous les fuyez, mais ils s'accumulent à votre vue parce que vous les collez les uns sur les autres avec addSubview :.

Atteindre le réseau pendant un prélèvement de cellules est incroyablement lent et bloque votre interface utilisateur. Si ces URL sont locales, vous pouvez utiliser + imageWithContentsOfFile de UIImage, sinon, vous devez charger ceci en arrière-plan.

Je ne pense pas que vous ayez besoin d'un fil ici. NSURLConnection est un excellent moyen de charger des données en arrière-plan sans encourir la surcharge du thread.

nessence est complètement correct que vous avez besoin d'une classe de modèle pour Story. Votre approche de base de la configuration des cellules réutilisables est incorrecte.

Vous ne récupérez pas une cellule réutilisable, puis ajoutez des sous-vues à celle-ci. Toutes vos sous-vues doivent être ajoutées dans le bloc if() pour créer la cellule. Ensuite, à chaque passage, vous changez simplement les valeurs des choses. J'ai réécrit une partie de votre code ci-dessous pour le démontrer. Ce code n'est toujours pas correct, car il atteint le réseau lors d'un tirage de cellule, et il peut y avoir trop d'éléments dans une cellule de sous-vue (plutôt qu'une cellule personnalisée), mais c'est plus proche de la bonne idée. Je ne sais même pas si cela compile; Je l'ai juste tapé ici.

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 

    static NSString *MyIdentifier = @"MyIdentifier"; 
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:MyIdentifier]; 

    if (cell == nil) { 
     // Here we do all our cell creation 
     cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:MyIdentifier] autorelease]; 

     // Make the label 
     CGRect aframe = CGRectMake(80, 30, 250, 40); 
     UILabel *textLabel = [[[UILabel alloc] initWithFrame:aframe] autorelease]; // Note the -autorelease so we don't leak 

     textLabel.font = [UIFont boldSystemFontOfSize:14]; 
     textLabel.numberOfLines=0; 
     textLabel.textColor = [UIColor darkTextColor]; 
     textLabel.backgroundColor = [UIColor whiteColor]; 
     textLabel.tag = DescriptionTag; // A tag so we can find it later (you'll need a constant for this) 
     [cell.contentView addSubview:textLabel]; 

     // And the second label 
     aframe = CGRectMake(80, 30, 250, 40); 
     textLabel = [[[UILabel alloc] initWithFrame:aframe] autorelease]; 
     textLabel.font = [UIFont boldSystemFontOfSize:14]; 
     textLabel.numberOfLines=0; 
     textLabel.textColor = [UIColor darkTextColor]; 
     textLabel.backgroundColor = [UIColor whiteColor]; 
     textLabel.tag = TitleTag; 
     [cell.contentView addSubview:textLabel]; 

     // The image view 
     CGRect frame = CGRectMake(0, 0, 70,80); 
     UIImageView *topImageView = [[[UIImageView alloc] init] autorelease]; 
     topImageView.frame = frame; 
     topImageView.tag = TopImageTag; 
     [cell.contentView addSubview:topImageView]; 
    } 

    // all the above was cell creation; we do that as seldom as possible. 
    // Now we do cell configuration. We want this to be fast. 

    UILabel *descriptionLabel = (UILabel*)[cell.contentView viewWithTag:DescriptionTag]; 
    descriptionLabel.text = itemDescription; 

    UILabel *titleLabel = (UILabel*)[cell.contentView viewWithTag:TitleTag]; 
    titleLabel.text =[[stories objectAtIndex:indexPath.row] objectForKey:@"title"]; 

    NSString *imageURLString = [m_imglinkArray objectAtIndex:storyIndex]; // You should have a model class called Story, not two arrays. 
    UIImage *image = [[[UIImage alloc] initWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:imageURLString]]] autorelease]; // This is still way too slow if it's a remote URL 
    UIImageView *imageView = (UIImageView*)[cell.contentView viewWithTag:TopImageTag]; 
    imageView.image = image;  

    return cell; 
} 

Je vous recommande de passer un peu de temps de qualité étudier TableViewSuite, Practical Memory Management et Coding Guidelines for Cocoa. Un peu de temps à étudier les bases du cacao serait également utile, car le style de codage indique que vous n'avez peut-être pas de base solide. Bien que ce soit un livre Mac, je recommande toujours Cocoa Programming for Mac OS X. Si vous êtes intéressé à utiliser ceci pour apprendre l'iPhone, j'ai mis en place un syllabus qui pourrait aider. Je ne l'ai pas encore examiné, mais le CS193P course de Stanford en ligne semble prometteur.

1

Cela a été demandé plusieurs fois ici, ce que vous devez faire est de charger de façon asynchrone les images pour chaque cellule afin d'empêcher le défilement de ralentir.

Ceci est appelé « image Lazy chargement » et je fais référence le tutoriel pomme ici: Lazy load images in UITableView

Questions connexes