2015-04-06 47 views
1

我想寫公共函數加載圖像異步並返回UIImage。我想用它來填充圖像的UITableView。公共函數加載圖像異步並返回UIImage

class CommonFunctions { 

func loadImageAsync(StringURL: NSString) -> UIImage{ 

    var returningImage = UIImage() 

    let url = NSURL(string: StringURL) 

    let requestedURL = NSURLRequest(URL: url!) 

    NSURLConnection.sendAsynchronousRequest(requestedURL, queue: NSOperationQueue.mainQueue(), completionHandler: { 
     response, data, error in 

     if error != nil { 
      println("there is some error loading image") 
     } 
     else { 

      if let image = UIImage(data: data){ 
       returningImage = image 
      } 
     } 
    }) 
    return returningImage 
    } 

} 

的問題是,當我要使用此功能:

cell.imageModelImage.image = CommonFunctions.loadImageAsync(CommonFunctions) 

而是字符串參數我得到的類?爲什麼?

+0

爲什麼你將CommonFunctions作爲參數傳遞給loadImageAsyn()?爲什麼你將實例方法稱爲類方法? – Abdullah 2015-04-06 10:32:35

回答

2

你問:

而是字符串參數我得到的類?爲什麼?

這是因爲您將其稱爲是類函數,但並未將其定義爲類。如果在函數聲明中添加class關鍵字,則不會看到該行爲。

但是這裏有更深層次的問題:你不能從一個異步函數返回一個值(因爲這個函數會在異步請求不會完成時立即返回)。

一種解決方案是提供一個完成處理程序,如果圖像檢索成功,將調用:

class func loadImageAsync(stringURL: String, completion: @escaping (UIImage?, Error?) -> Void) { 
    let url = URL(string: stringURL)! 

    URLSession.shared.dataTask(with: url) { data, response, error in 
     guard let data = data, error == nil else { 
      DispatchQueue.main.async { completion(nil, error) } 
      return 
     } 
     let image = UIImage(data: data) 
     DispatchQueue.main.async { completion(image, nil) } 
    }.resume() 
} 

注意,我分派完成處理程序返回到主隊列,所有的UI更新應發生。

然後,在tableView(_:cellForRowAt:),你可以提供一個將被調用時,異步請求完成框:

cell.imageModelImage.image = ... // remember to initialize image view before starting async method 
CommonFunctions.loadImageAsync(with: "http://example.com/test.jpg") { image, error in 
    if let cell = tableView.cellForRow(at: indexPath) as? CustomCell { // make sure cell hasn't scrolled out of view 
     cell.imageModelImage.image = image 
    } 
} 

注意,上面的假設是不可能在其間插入行的表一段的時間。如果這個假設無效,而不是使用舊的indexPath,那麼當調用異步完成處理程序時,您可能需要重新查詢您的模型以確定哪些IndexPath對此單元格有效。

對於Swift 2翻譯,請參閱此答案的previous revision

+0

哪種方法是Swift的首選方法? – jonas 2015-07-07 04:43:43