2017-01-23 4 views
1

Im die Bildverbindung von einem json herunterzuladen und dann das Bild erzeugt wird, sobald die Tabellenansicht seine Zellen beginnen zu schaffen:aktualisiert Tabellenzelle Bild asynchron

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 

     let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! TableViewCellController 

      DispatchQueue.main.async(execute: {() -> Void in 

       if let url = NSURL(string: self.movies[indexPath.row].image) 
       { 

        if let data = NSData(contentsOf: url as URL) 
        { 
         let imageAux = UIImage((data: data as Data)) 
         cell.movieImage.image = imageAux 
         self.tableView.reloadData() 

        } 
       } 
      }) 

     cell.name = self.movies[indexPath.row].name 
     cell.date = self.movies[indexPath.row].date 
     return cell 
} 

Und das funktioniert gut, aber die Tabellenansicht wird wirklich langsam, nicht beim Rendern, sondern beim Scrollen. Ich überprüfe den RAM und die CPU und beide sind wirklich niedrig, aber meine Netzwerknutzung steigt weiter, aber die Bilder sind bereits auf der Zelle, so dass es bereits fertig ist. (Für diesen Test im Aufruf des JSON für nur 2 Filme, also 2 Bilder)

Bevor ich anfing dies war mein Gesamtdownload etwa 200kb (mit Bildern), jetzt wird es über 2MB, bevor ich das Projekt zu stoppen.

Was mache ich falsch?

Antwort

3

Wahrscheinlich möchten Sie eine separate Warteschlange für Hintergrundaktivitäten festlegen. In diesem Fall ist Ihre starke Netzwerkaufgabe:

NSData(contentsOf: url as URL)

Dies ist, was die Benutzeroberfläche ist die „Einfrieren“. Die beste Lösung wäre so etwas wie DispatchQueue.background zu definieren und die Netzwerk-Anrufe dort ausführen, während dann später die UI-Aufgaben wieder auf dem Haupt-Thread durchführen, um nicht Ihre Anzeige zu sperren:

DispatchQueue.background.async(execute: {() -> Void in 
    if let url = NSURL(string: self.movies[indexPath.row].image) { 
     //Do this network stuff on the background thread 
     if let data = NSData(contentsOf: url as URL) { 
      let imageAux = UIImage(data: data as Data) 
      //Switch back to the main thread to do the UI stuff 
      DispatchQueue.main.async(execute: {() -> Void in 
       cell.movieImage.image = imageAux 
      } 
     } 
    } 
}) 

mich, wenn diese wissen lassen macht Sinn.

+0

Vielen Dank! Ein weiteres Problem war, dass ich den Tisch nicht neu laden musste, damit die Bilder dutzende Male heruntergeladen wurden (irgendwie offensichtlich, aber ich sah es zuerst nicht). Vielen Dank Michael! – Adrian

+0

Michael Fourre Ich weiß, dass dies nicht die Frage war, aber ich merke, dass ich ein Problem habe, da ich jedes Mal, wenn ich die Zelle hoch- oder runterscrolle, die Bilder wieder aus der Warteschlange bringe, wie könnte ich das vermeiden? Vielen Dank! – Adrian

+2

Ich würde die Bilder zwischenspeichern @Adrian Blick in die 'NSCache' Dokumentation. Es ist ziemlich einfach zu benutzen. Wenn du eine andere Frage postest, könnte ich ein Snippet von meinem UIImage Caching Code als Beispiel hinzufügen –

Verwandte Themen