Swift 加载映像异步并返回UIImage的公共函数

Swift 加载映像异步并返回UIImage的公共函数,swift,asynchronous,uiimage,load,Swift,Asynchronous,Uiimage,Load,我正在尝试编写一个公共函数,用于异步加载图像并返回UIImage。我想在用图像填充UITableView时使用它 class CommonFunctions { func loadImageAsync(StringURL: NSString) -> UIImage{ var returningImage = UIImage() let url = NSURL(string: StringURL) let requestedURL = NSURLRequest

我正在尝试编写一个公共函数,用于异步加载图像并返回UIImage。我想在用图像填充UITableView时使用它

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)
我得到的不是字符串参数,而是类?为什么会这样?你会问:

我得到的不是字符串参数,而是类?为什么会这样

这是因为您调用它就像调用一个类函数一样,但没有这样定义它。如果在函数声明中添加
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(uquo: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
    }
}
注意,上面假设在中间的时间段内不可能在表中插入行。如果该假设无效,而不是使用旧的
indepath
,则可能需要重新查询模型,以确定在调用异步完成处理程序时,哪些
indepath
对该单元格有效


有关Swift 2格式副本,请参阅此答案的结尾。

为什么要将CommonFunctions作为参数传递给loadImageAsyn()?为什么将实例方法称为类方法?哪种方法是Swift的首选方法?