Swiftasynchronous加载图像
我正在从urlasynchronous工作显示图像。 我试图创build一个新的线程下载图像,然后刷新main thread
。
func asyncLoadImg(product:Product,imageView:UIImageView){ let downloadQueue = dispatch_queue_create("com.myApp.processdownload", nil) dispatch_async(downloadQueue){ let data = NSData(contentsOfURL: NSURL(string: product.productImage)!) var image:UIImage? if data != nil{ image = UIImage(data: data!) } dispatch_async(dispatch_get_main_queue()){ imageView.image = image } } }
当我试图debugging,当谈到dispatch_async(downloadQueue),它跳出了func。 任何build议? 谢谢
Swift 3更新代码:
extension UIImageView { public func imageFromServerURL(urlString: String) { URLSession.shared.dataTask(with: NSURL(string: urlString)! as URL, completionHandler: { (data, response, error) -> Void in if error != nil { print(error) return } DispatchQueue.main.async(execute: { () -> Void in let image = UIImage(data: data!) self.image = image }) }).resume() }}
Swift 2.2代码:
extension UIImageView { public func imageFromServerURL(urlString: String) { NSURLSession.sharedSession().dataTaskWithURL(NSURL(string: urlString)!, completionHandler: { (data, response, error) -> Void in if error != nil { print(error) return } dispatch_async(dispatch_get_main_queue(), { () -> Void in let image = UIImage(data: data!) self.image = image }) }).resume() }}
现在,无论你需要什么,只要这样从服务器url加载图像:
UIImageView.imageFromServerURL(“这里服务器url”)。
简单!
在Swift3
使用extension
。 要解决networking问题,我build议你使用NSCache
:
import UIKit let imageCache = NSCache<NSString, AnyObject>() extension UIImageView { func loadImageUsingCache(withUrl urlString : String) { let url = URL(string: urlString) self.image = nil // check cached image if let cachedImage = imageCache.object(forKey: urlString as NSString) as? UIImage { self.image = cachedImage return } // if not, download image from url URLSession.shared.dataTask(with: url!, completionHandler: { (data, response, error) in if error != nil { print(error!) return } DispatchQueue.main.async { if let image = UIImage(data: data!) { imageCache.setObject(image, forKey: urlString as NSString) self.image = image } } }).resume() } }
希望它有帮助!
从Shobhakar Tiwari的回答开始,我认为在这些情况下,如果出现错误和出于加载目的,通常会有一个默认图像,所以我已经更新了它,以包含一个可选的默认图像:
Swift 3
extension UIImageView { public func imageFromServerURL(urlString: String, defaultImage : String?) { if let di = defaultImage { self.image = UIImage(named: di) } URLSession.shared.dataTask(with: NSURL(string: urlString)! as URL, completionHandler: { (data, response, error) -> Void in if error != nil { print(error ?? "error") return } DispatchQueue.main.async(execute: { () -> Void in let image = UIImage(data: data!) self.image = image }) }).resume() } }
这里这个代码可能会帮助你。
let cacheKey = indexPath.row if(self.imageCache?.objectForKey(cacheKey) != nil){ cell.img.image = self.imageCache?.objectForKey(cacheKey) as? UIImage }else{ dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), { if let url = NSURL(string: imgUrl) { if let data = NSData(contentsOfURL: url) { let image: UIImage = UIImage(data: data)! self.imageCache?.setObject(image, forKey: cacheKey) dispatch_async(dispatch_get_main_queue(), { cell.img.image = image }) } } }) }
有了这个图像将下载和caching没有落后的表视图滚动
这个解决scheme使滚动速度非常快,没有不必要的图像更新。 您必须将url属性添加到我们的单元格类中:
class OfferItemCell: UITableViewCell { @IBOutlet weak var itemImageView: UIImageView! @IBOutlet weak var titleLabel: UILabel! var imageUrl: String? }
并添加扩展名:
import Foundation import UIKit let imageCache = NSCache<AnyObject, AnyObject>() let imageDownloadUtil: ImageDownloadUtil = ImageDownloadUtil() extension OfferItemCell { func loadImageUsingCacheWithUrl(urlString: String ) { self.itemImageView.image = nil if let cachedImage = imageCache.object(forKey: urlString as AnyObject) as? UIImage { self.itemImageView.image = cachedImage return } DispatchQueue.global(qos: .background).async { imageDownloadUtil.getImage(url: urlString, completion: { image in DispatchQueue.main.async { if self.imageUrl == urlString{ imageCache.setObject(image, forKey: urlString as AnyObject) self.itemImageView.image = image } } }) } } }
你也可以改进它,并提取一些代码到一个更一般的单元格类,即CustomCellWithImage,使其更加可重用。