2 Stimmen

Warum werden die UItableViewCell-Bilder erst geladen, wenn gescrollt wird?

Mein Code lädt Bilder asynchron herunter, indem er InternetImage im tableView:cellForRowAtIndexPath: Methode verwendet. Dabei initialisiert er ein IntentImage mit initWithURL und ruft downloadImage auf. Dieser Code funktioniert einwandfrei, nachdem man zu einer neuen Zelle UITableViewCell in der UITableView gescrollt ist, aber davor nicht, obwohl die URL in beiden Fällen korrekt ist. Keine der NSURLConnection-Delegate-Methoden von InternetImage wird aufgerufen, um mich über Erfolg oder Misserfolg der Verbindung zu informieren, wie es eigentlich sollte. Das Aufrufen von reloadData:, setNeedsDisplay: und setNeedsLayout: bewirkt nichts, da das Bild nicht heruntergeladen wird.

Hier ist der Code aus meiner Unterklasse von UITableViewController:

   - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
        Object *object = (Object *)[self.array objectAtIndex:indexPath.row];

        UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell"];
        if (cell == nil) {
            cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:@"cell"] autorelease];
        }

        cell.textLabel.text = object.attribute;

        if (object.image == nil && object != nil) {
            NSString *URLString = [[MyAppDelegate imageURLFromLink:(object.link) withExtension:@".jpg"]absoluteString];

            InternetImage *asynchImage = [[InternetImage alloc] initWithUrl:URLString object:object];
            [asynchImage downloadImage:self];
        }

        cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;

        if (object.image != nil && object.thumbnailImage == nil) {

            UIImage *image= (UIImage *) object.image;
            UIImage *thumbnail = [image _imageScaledToSize:CGSizeMake(75.0, 50.0) interpolationQuality:20];
            object.thumbnailImage = thumbnail;
        }
        cell.imageView.image = object.thumbnailImage;

        return cell;
    }

0voto

Louis Gerbarg Punkte 43196

Also, es ist nicht ganz klar aus Ihrer Beschreibung, was passiert, wenn Sie scrollen. Offensichtlich funktionieren nachfolgende Anrufe, aber beginnen alle zuvor versuchten Verbindungen zu diesem Zeitpunkt plötzlich oder gehen sie komplett verloren?

Was nun das Geschehen betrifft, so glaube ich aufgrund der genannten Gründe nicht, dass jemand mehr tun kann, als Ihnen einige Vermutungen anzustellen. Wenn ich raten müsste, dann würde ich vermuten, dass, wenn das, was ich im letzten Absatz gesagt habe, passiert, Ihr Problem darin besteht, dass (aus welchem Grund auch immer) der Haupt-Threads-Runloop die NSURLConnections-Ereignisse nicht verarbeitet, bis etwas den Motor anspringen lässt. Dies könnte aus einer Vielzahl von Gründen passieren, zum Beispiel weil der Runloop im falschen Modus ist. Sie könnten versuchen, den NSRunLoop manuell zu starten oder zu ändern, um InternetImage explizit Runloop zu setzen oder den Download manuell zu starten.

Zwei schnelle Randbemerkungen

  1. InternetImage scheint viele Dinge zu tun, die nicht idiomatisch mit den allgemeinen Cocoa-Programmierkonventionen übereinstimmen. Zumindest für mich macht das es schwieriger, schnell zu lesen, und ich bin mir nicht ganz sicher, ob es die Dinge richtig macht.
  2. Verwenden Sie nicht _imageScaledToSize:. Das ist eine private Apple-Methode, und wenn sie bemerken, dass Sie sie verwenden, könnte das zu einer Ablehnung führen.

0voto

MostlyYes Punkte 199

Ich habe keine Antwort, aber ich kann Ihnen sagen, dass ich das gleiche Problem sehe.

Ich verwende eine leicht modifizierte Version von Mark Johnsons AsyncImageView Klasse. Die asynchronen Anfragen für die Bilder rufen keine Delegaten auf, bis ich die Tabelle scrollen. Sobald ich eine Zelle aus dem Blickfeld scrolle und zurück, wird der Aufruf erneut ausgeführt und die Daten ordnungsgemäß abgerufen.

Ich habe gelesen, dass NSURLConnection von einem bestimmten Modus des Run-Loops abhängt - ich weiß nicht, ob das bei einem Szenario eine Rolle spielt, bei dem eine URL-Verbindungsanfrage in tableView:cellForIndexPath gestartet wird.

Wie würde man vorgehen, um die internen NSURLConnection-Funktionen zu debuggen?

[UPDATE]

Also habe ich mein spezielles Problem gelöst, indem ich die Verbindung explizit im Hauptthread gestartet habe. Ich habe den Code für die Verbindungs Einrichtung in einem anderen Selector platziert und diesen über performSelectorOnMainThread aufgerufen, und alles war wieder gut.

Sie sollten versuchen, das aktuelle Runloop-Modus im Selector zu protokollieren, der die Verbindung startet - ich habe festgestellt, dass es nicht der Standard-Runloop-Modus war, den NSUrlConnection benötigt.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X