2016-03-10 1 views
2

J'ai une table qui affiche des informations sur une liste d'objets en cours de téléchargement. Chaque cellule contient un UIProgressView qui est mis à jour en fonction de la progression de ce téléchargement. Mon problème est que pendant le téléchargement et la mise à jour de cette vue d'avancement, tout est très lent, et le CPU est surveillé à 100% ou plus dans le navigateur de débogage de Xcode.Une table avec des cellules qui ont toutes leurs propres vues de progression est très lente

Chaque objet est stocké avec sa propre propriété de progression.

class Download { 
    var id: String = "" 
    var progress: Float = 0 
} 

Et j'ai un tableau de ces derniers:

var downloads = [Download]() 

Ceci est réglé sur le tableView dans mon contrôleur de vue en utilisant cellForRowAtIndexPath: en utilisant quelque chose le long des lignes de:

let download = downloads[indexPath.row] 
cell.progressView.progress = download.progress 

I J'utilise Alamofire pour gérer mes téléchargements et en utilisant la fermeture de progression incluse, je suis en train de mettre à jour les progrès des téléchargements:

download.progress = Float(bytesRead)/Float(bytesExpected) 

dispatch_async(dispatch_get_main_queue()) { 
    self.tableView.reloadData() 
} 

C'est à ce stade que je pense que le goulot d'étranglement se produit en raison du grand nombre de mises à jour qui se produisent. Pour essayer de limiter le problème, j'ai essayé de mettre à jour une seule cellule comme il a été changé:

let rowIndex = self.downloads.indexOf() { $0.id == download.id }     
let indexPath = NSIndexPath(forRow: rowIndex!, inSection: 0) 

dispatch_async(dispatch_get_main_queue()) { 
    self.tableView.reloadRowsAtIndexPaths([indexPath], withRowAnimation: .None) 
} 

Cependant, je trouve que cela a causé tout pour aller encore plus lent.

Toutes les suggestions seraient grandement appréciées, merci d'avance!

+0

Le problème est que vous rechargez toute la vue de table, au lieu de simplement mettre à jour UIProgressView. – almas

Répondre

3

Le bloc de progression de téléchargement peut être déclenché plusieurs fois par seconde, et le rechargement de l'ensemble de la vue de table est coûteux et inefficace. Ce que vous devez faire à la place est de surveiller la progression du téléchargement dans chaque cellule de vue de table individuellement. Voici comment vous pouvez le faire. Dans votre tableviewcell:

var progressTimer: NSTimer? 

    var download: Download? { 
    didSet { 
     guard let download = download else { 
     // cancel your timer here 
     return 
     } 
     // start NSTimer here to update UIProgressView every second 
    } 
    } 

    func prepareForReuse() { 
    super.prepareForReuse() 
    download = nil 
    } 

Dans votre contrôleur de vue:

override func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, 
    forRowAtIndexPath indexPath: NSIndexPath) { 
     cell.download = downloads[indexPath.row] 
    } 
+0

Merci pour cela! Certainement réduit la charge, encore un peu lent, mais je suis sûr que cela est dû à tout ce qui se passe dans l'application: \ –

+0

Heureux qui a aidé. Vous pouvez utiliser Time Profiler pour identifier ce qui ralentit l'application. Ou simplement commenter des morceaux de code et voir comment se comporte l'application. Par exemple, commentez "cell.download = downloads [indexPath.row]", afin que les cellules cessent de suivre toute progression, puis testez la réactivité. – almas

0

Votre tentent de recharger la table ou la cellule lorsque les progrès mis à jour, qui est lourd.

Depuis les progressViews ont été créés, essayez de les réutiliser, vous pouvez obtenir une instance de progressView en utilisant Tag:

let rowIndex = self.downloads.indexOf() { $0.id == download.id } 
    let indexPath = NSIndexPath(forRow: rowIndex, inSection: 0) 


    let cell = tableView.cellForRowAtIndexPath(indexPath) 

    let progressView = cell?.viewWithTag(100) // Tag your progressView as 100 

    progressView.progress = download.progress 

aller plus loin, vous pouvez aussi régler les performances que de mettre à jour des progrès toutes les 0,5 secondes ou moins , tant que l'utilisateur le sent bien. Mais pas pour tous les progrès, ce serait trop fréquent.