2016-05-31 1 views
0

Je souhaite afficher l'image dans TableViewCell. Il y a les codes:TableView Image d'affichage de cellule avec dispatch_async affiche "valeur de retour inattendue non-vide dans la fonction void" numéro

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { 
     let cellIdentifier = "myCell" 
     let cell = tableView.dequeueReusableCellWithIdentifier(cellIdentifier, forIndexPath: indexPath) as! DIYSquareALLCell 
     cell.titles!.text = titles[indexPath.row] 
     cell.leftImages!.image = getPic(leftImages[indexPath.row]) 
     return cell 
    } 

func getPic(PicURL: String) -> UIImage! { 
     let image = self.imageCache[PicURL] as UIImage? 
     if image == nil { 
      let url = NSURL(string: PicURL.stringByAddingPercentEncodingWithAllowedCharacters(NSCharacterSet.URLQueryAllowedCharacterSet())!) 
      if let data = NSData(contentsOfURL: url!) { 
       imageCache[PicURL] = UIImage(data: data) 
       return UIImage(data: data)! 
      } 
     } else { 
      return image 
     } 
     return nil 
    } 

Mais le défilement est très TableView lag si je change la fonction et ajouter une fonction de dispatch_async en elle.

Il affiche le problème "valeur de retour non-vide inattendue dans la fonction void" dans ma fonction getPic.

Après avoir changé, il y a les codes:

func getPic(PicURL: String) -> UIImage! { 
     let image = self.imageCache[PicURL] as UIImage? 
     if image == nil { 
      let url = NSURL(string: PicURL.stringByAddingPercentEncodingWithAllowedCharacters(NSCharacterSet.URLQueryAllowedCharacterSet())!) 
      let priority = DISPATCH_QUEUE_PRIORITY_HIGH 
      dispatch_async(dispatch_get_global_queue(priority, 0)) { 
       let data = NSData(contentsOfURL: url!) 
       if data != nil { 
        dispatch_async(dispatch_get_main_queue(), {() -> Void in 
         self.imageCache[PicURL] = UIImage(data: data!) 
         return UIImage(data: data!)// here is the issue 
        }) 
       } 
      } 
     } else { 
      return image 
     } 
     return nil 
    } 

Tout le monde peut me dire comment résoudre ce problème? Merci!

Répondre

0

Vous ne pouvez pas renvoyer une valeur à un objet lorsque vous utilisez la tâche asynchrone. La fonction qui s'exécute sur le thread principal n'attendra pas que votre tâche asynchrone soit terminée. Pour ce faire, utilisez le Closure.

Votre code devrait ressembler à ceci:

typealias CompletionHandler = (image: UIImage) -> Void 
    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { 
     let cell: testCell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as! testCell 
     downloadFileFromURL(NSURL(string: "http://img.youtube.com/vi/PCwL3-hkKrg/sddefault.jpg")!, completionHandler:{(img) in 
      dispatch_async(dispatch_get_main_queue(), {() -> Void in 
       cell.imgView.image = img 
      }) 

      }) 
     return cell 
    } 

    func downloadFileFromURL(url1: NSURL?,completionHandler: CompletionHandler) { 
     // download code. 
     if let url = url1{ 
     let priority = DISPATCH_QUEUE_PRIORITY_HIGH 
     dispatch_async(dispatch_get_global_queue(priority, 0)) { 
      let data = NSData(contentsOfURL: url) 
      if data != nil { 
       print("image downloaded") 
       completionHandler(image: UIImage(data: data!)!) 
      } 
      } 
     } 
    } 

Exemple de projet chargé de GIT.

+1

aimez-vous bro ... –