TableView big Image performance

Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

  • TableView big Image performance

    Servus Leute,
    habe Heute noch eine Frage an euch.
    ich habe ein TableView mit Großen Bildern und leider lagt der TableView beim scrollen.
    ihr einmal mein code:

    Quellcode

    1. - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
    2. {
    3. UITableViewCell *cell = (UITableViewCell*)[tableView dequeueReusableCellWithIdentifier:@"MHSeminarCell" forIndexPath:indexPath];
    4. if(cell != nil) {
    5. dispatch_async(dispatch_get_main_queue(), ^{
    6. cell.imageView.image = [MHNetworkEngine getModulImageByData:(NSDictionary*)[self.seminars objectAtIndex:indexPath.row]];
    7. [cell setNeedsLayout];
    8. });
    9. cell.textLabel.text = [[self.seminars objectAtIndex:indexPath.row] valueForKey:kNETWORKENGINE_SEMINAR_TOWN];
    10. cell.detailTextLabel.text = [[self.seminars objectAtIndex:indexPath.row] valueForKey:kNETWORKENGINE_SEMINAR_BEGIN];
    11. }
    12. return cell;
    13. }
    Alles anzeigen

    Ich muss wahrscheinlich die Bilder in der drawrect mit Zeichen lassen.
    oder was kann ich noch tun ?
  • Habe bisher noch keine Bilder für einen TableView aus dem Netz nachgeladen, aber der o.a. Code sieht für mich auf den ersten Blick nicht korrekt aus.

    Je nachdem wie lange das Laden des Bildes benötigt und wie schnell man scrollt wird die Zelle evtl. bereits für eine andere Zeile wiederverwendet und dann hast Du ein falsches Bild in dieser Zelle.

    Welche Auflösung haben die geladenen Bilder und wie viele Pixel hat der ImageView für die Anzeige?
  • oh man bin ich blöd das kommt davon wenn man zu viel in titanium studio macht :(
    jetzt geht es gut hier der aktuelle code:

    Quellcode

    1. - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
    2. {
    3. UITableViewCell *cell = (UITableViewCell*)[tableView dequeueReusableCellWithIdentifier:@"MHSeminarCell" forIndexPath:indexPath];
    4. if(cell != nil) {
    5. dispatch_async(dispatch_get_main_queue(), ^{
    6. if([self.seminarImages objectAtIndex:indexPath.row]) {
    7. cell.imageView.image = (UIImage*)[self.seminarImages objectAtIndex:indexPath.row];
    8. } else {
    9. UIImage *image = [MHNetworkEngine getModulImageByData:(NSDictionary*)[self.seminars objectAtIndex:indexPath.row]];
    10. [self.seminarImages addObject:image];
    11. cell.imageView.image = image;
    12. }
    13. [cell setNeedsLayout];
    14. });
    15. cell.textLabel.text = [[self.seminars objectAtIndex:indexPath.row] valueForKey:kNETWORKENGINE_SEMINAR_TOWN];
    16. cell.detailTextLabel.text = [[self.seminars objectAtIndex:indexPath.row] valueForKey:kNETWORKENGINE_SEMINAR_BEGIN];
    17. }
    18. return cell;
    19. }
    Alles anzeigen
  • das passt aber immer nocht nicht.

    du überprüfst indexe, wirfst bilder aber einfach rein (reihenfolge stimmt nicht).

    auch musst du aufpassen weil das ganze nebneläufig passiert (di liest und änderst wohl das gleiche array gleichzeitig).

    und das original-problem ist immer noch vorhanden dass du ein image setzt das gar nicht mehr für dich bestimmt ist sondern eventuell schon eine andere row representiert.
  • Warum ? läuft das nicht auf das selber hinaus wenn ich einfach das mache ?

    Quellcode

    1. NSData * imageData = [[NSData alloc] initWithContentsOfURL: [NSURL URLWithString: urlString]];
    2. UIImage *image = [UIImage imageWithData: imageData];
  • gritsch schrieb:

    das passt aber immer nocht nicht.

    du überprüfst indexe, wirfst bilder aber einfach rein (reihenfolge stimmt nicht).

    auch musst du aufpassen weil das ganze nebneläufig passiert (di liest und änderst wohl das gleiche array gleichzeitig).

    und das original-problem ist immer noch vorhanden dass du ein image setzt das gar nicht mehr für dich bestimmt ist sondern eventuell schon eine andere row representiert.


    Ahh stimmt mist :(
  • Markus Müller schrieb:

    Schonmal AFNetworking angeschaut? Da gibt es eine UIImageView Kategorie für:

    github.com/AFNetworking/AFNetw…mageView%2BAFNetworking.h

    Quellcode

    1. [cell.imageView setImageWithURL:imageURL placeholderImage:[UIImage imageNamed:@"profile-image-placeholder"]];

    cocoanuts.mobi/2014/04/27/fastscroll/

    Beste Grüße, Markus


    Danke aber ich will lieber das Rad noch einmal neu erfinden xd

    ich habe noch einmal mein versuch von vorher getestet also das hier

    Quellcode

    1. dispatch_async(dispatch_get_main_queue(), ^{
    2. if([self.seminarImages objectAtIndex:indexPath.row]) {
    3. cell.imageView.image = (UIImage*)[self.seminarImages objectAtIndex:indexPath.row];
    4. } else {
    5. UIImage *image = [MHNetworkEngine getModulImageByData:(NSDictionary*)[self.seminars objectAtIndex:indexPath.row]];
    6. cell.imageView.image = image;
    7. [self.seminarImages insertObject:image atIndex:indexPath.row];
    8. }
    9. [cell setNeedsLayout];
    10. });
    11. cell.textLabel.text = [[self.seminars objectAtIndex:indexPath.row] valueForKey:kNETWORKENGINE_SEMINAR_TOWN];
    12. cell.detailTextLabel.text = [[self.seminars objectAtIndex:indexPath.row] valueForKey:kNETWORKENGINE_SEMINAR_BEGIN];
    Alles anzeigen


    und eigentlich geht das ich bekomme die richtige Daten zur cell auch wenn ich wie ein verrücken hin und her scrolle und ich denke ich habe mal irgend wo gelesen das ein block die variablen kopiert oder irgend wie sowas wahrscheinlich nerv ich euch mit der ganzen Fragerei :)
  • du hast nur glück!

    1. überprüfen ob das bild schon da ist solltest du noch vor dem dispatch_async.

    2. du solltest die bilder an die objekte hängen in dem auch die anderen infos drin sind.
    dann kannst du auch einen status dazupacken ob es gerade schon geladen wird.

    3. du musst aufpassen wenn du aus dem thread raus objekte dem array hinzufügst.

    4. die reihenfolge ist nicht immer korrekt (hängt vom scrollen, laden etc ab). deswegen siehe punkt 2.

    5. du sollst das bild nur setzen wenn es noch für die cell das richtige bild ist. setze einfach vor dem laden (vor dem asynch) die objectRepresentation und überprüfe diese vor dem setzen des bildes.
  • gritsch schrieb:

    das klappt aber nur wenn die cells nicht wiederverwendet werden (scrollen).

    Nö, eben nicht; du musst schon den ganzen Abschnitt lesen. ;)

    Schau dir Listing 9.55 an: Der Block holt sich die sichtbare Zelle mit dem angegebenen Indexpfad. Dadurch lädt die App das Bild genau in die Zelle, für die sie Anfrage gestartet hat.
    „Meine Komplikation hatte eine Komplikation.“
  • macmoonshine schrieb:

    gritsch schrieb:

    das klappt aber nur wenn die cells nicht wiederverwendet werden (scrollen).

    Nö, eben nicht; du musst schon den ganzen Abschnitt lesen. ;)

    Schau dir Listing 9.55 an: Der Block holt sich die sichtbare Zelle mit dem angegebenen Indexpfad. Dadurch lädt die App das Bild genau in die Zelle, für die sie Anfrage gestartet hat.


    du meinst den code hier?

    Quellcode

    1. ​completionHandler:^( NSURLResponse *inResponse, NSData *inData, NSError *inError)
    2. {
    3. YouTubeCell *theCell = (YouTubeCell *) [inCollectionView cellForItemAtIndexPath: inIndexPath];


    der code holt sich immer eine cell. ob die nun sichtbar ist oder nicht.