2015-10-26 59 views
0

我遇到問題。我想從互聯網下載圖像,並在下載時顯示「指示器」。問題是當沒有互聯網連接時,方法「已下載從」進入「」如果錯誤!=無「,並因此」指標「永遠不會中斷。這是我的代碼。NSURLSession返回數據

var imageArray:[String]! = ["http://findicons.com/files/icons/1072/face_avatars/300/a01.png", "http://findicons.com/files/icons/1072/face_avatars/300/a02.png", "http://findicons.com/files/icons/1072/face_avatars/300/a03.png", "http://findicons.com/files/icons/1072/face_avatars/300/a04.png", "http://findicons.com/files/icons/1072/face_avatars/300/a05.png"] 

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { 
     let newCell = tableView.dequeueReusableCellWithIdentifier("userCell") as! UserCell_TableViewCell 
     let selectedUser = userArray[indexPath.row] 

     newCell.userDescription?.text = selectedUser.getFirstName() + " " + selectedUser.getLastName() 
      let randomNumber = arc4random_uniform(4) 
      let arrayIndex = Int(randomNumber) 
      let urlImage = imageArray[arrayIndex] 

      newCell.loadIndicator.startAnimating() 

      downloadedFrom(urlImage) { userImage in 
       dispatch_async(dispatch_get_main_queue()){ 
        newCell.userImage.image = userImage 
        newCell.loadIndicator.stopAnimating() 
       } 

       self.userArray[indexPath.row].setImage(userImage) 
      } 

     return newCell 
    } 

    func downloadedFrom(urlLink :String, completionHandler: (UIImage) ->()) 
    { 
     if let urlData = NSURL(string: urlLink) { 
      NSURLSession.sharedSession().dataTaskWithURL(urlData) { (data, response, error) in 
       if error != nil { 
        print("error=\(error)") 
        return 
       } else { 
        if let httpResponse = response as? NSHTTPURLResponse { 
         let userImage = httpResponse.statusCode == 200 ? UIImage(data: data!) : UIImage(named: "unknownImage") 

         completionHandler(userImage!) 
        }} 
       }.resume() 
     } 
    } 

編輯

import UIKit 

    class UserCell_TableViewCell: UITableViewCell { 

    @IBOutlet weak var userImage: UIImageView! 
    @IBOutlet weak var userDescription: UILabel! 
    @IBOutlet weak var loadIndicator: UIActivityIndicatorView! 

    override func awakeFromNib() { 
     super.awakeFromNib() 
     // Initialization code 
    } 

    override func setSelected(selected: Bool, animated: Bool) { 
     super.setSelected(selected, animated: animated) 

     // Configure the view for the selected state 
    } 

    func downloadedFrom(urlLink :String) 
    { 

     self.loadIndicator.startAnimating() 

     if let urlData = NSURL(string: urlLink) { 

      NSURLSession.sharedSession().dataTaskWithURL(urlData) { (data, response, error) in 

       if error != nil { 

        print("error = \(error)") 

        self.loadIndicator.stopAnimating() 

        return 

       } else { 

        // El servidor contesta la petición, pero la imágen puede no existir. 
        if let httpResponse = response as? NSHTTPURLResponse { 

         if httpResponse.statusCode == 200 { 

          dispatch_async(dispatch_get_main_queue()){ 

           self.userImage.image = UIImage(data: data!) 

           self.loadIndicator.stopAnimating() 

          }} 
        }} 

       }.resume() 
     } 

    } 

} 

    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { 

     let newCell = tableView.dequeueReusableCellWithIdentifier("userCell") as! UserCell_TableViewCell 
     let selectedUser = userArray[indexPath.row] 

     newCell.userDescription?.text = selectedUser.getFirstName() + " " + selectedUser.getLastName() 

      let randomNumber = arc4random_uniform(4) 

      let arrayIndex = Int(randomNumber) 

      let urlImage = imageArray[arrayIndex] 

      newCell.downloadedFrom(urlImage) 

     return newCell 
    } 

這使我這樣做的問題是,我需要你下載的圖像將其保存到一個數組,該方法的cellForRowAtIndexPath內的陣列完整性

回答

1

首先我想提一下,嘗試在表格單元格方法內調度加載循環(即使在單獨的線程中)也是不好的做法。您正在執行的程序塊將捕獲指針,因此如果在單元格移出表格並重新使用後加載圖像,則圖像將被加載到錯誤的表格單元格中。

解決此問題的最佳方法是將加載函數移入單元的類本身。因此,在配置單元時,只需將鏈接提供給單元,並讓單元處理圖像加載。

爲了解決最初的問題,您可以修改加載過程,以便在單元格離開表格時(如果調用prepareForReuse(),也可以),取消加載過程。

在單元格的類中,您可以添加一個互聯網連接檢查,以便在返回錯誤時停止指示器。當你將功能移動到單元的類時,這會變得更加清晰。

+0

感謝您的幫助。我是新人。你可以幫我多一點嗎?我編輯帖子,看看我是否理解他說的話。 – avechuche

+0

這看起來大多是正確的!您只需要解決單元移出屏幕時發生的問題。所以當這種情況發生時,單元格被標記爲重用,所以你想停止加載圖像(除非你不重用單元格)。這可以通過添加一個'BOOL'標誌來實現,並且當單元格不應該加載圖像時(在'prepareForReuse()'中)將其設置爲false。當圖像加載到您的downloadedFrom()中時,您需要檢查此標誌以查看是否真的應該加載圖像。 –