我的collectionViewCell中的图像是通过NSURLRequest获取和解析的,我如何缓存这些图像,以便他们不必在视图的每次出现/消失时都开始新的请求?
这是我的代码,用于获取图像:
class funnyPicture: NSObject {
var pfPicture : PFObject
var coverImage : UIImage!
init(pfPicture: PFObject) {
self.pfPicture = pfPicture
}
func fetchCoverImage(completion: (image: UIImage?, error: NSError?) -> Void) {
let urlString = self.pfPicture["funnyPictures"] as! String
let url = NSURL(string: urlString)
let request = NSURLRequest(URL: url!)
let queue = dispatch_get_main_queue()
NSURLConnection.sendAsynchronousRequest(request, queue: NSOperationQueue.mainQueue()) { (response: NSURLResponse?, data: NSData?, error: NSError?) in
if error == nil {
self.coverImage = UIImage(data: data!)
completion(image: self.coverImage, error: nil)
} else {
completion(image: nil, error: error)
}
}
}
}
这是我的collectionView代码,用于将图像解析为collectionViewCell:
override func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCellWithReuseIdentifier("Cell", forIndexPath: indexPath) as! MyCollectionViewCell
// Configure the cell
let book = self.books[indexPath.row]
let coverImage = book.coverImage
if coverImage == nil {
book.fetchCoverImage({ (image, error) -> Void in
if self.collectionView != nil {
collectionView.reloadItemsAtIndexPaths([indexPath])
}
})
} else {
dispatch_async(dispatch_get_main_queue()){
let imageView = cell.imageView
imageView.image = book.coverImage
}
};
if book.coverImage == nil {
cell.imageView.userInteractionEnabled = false
cell.userInteractionEnabled = false
}else {
cell.imageView.userInteractionEnabled = true
cell.userInteractionEnabled = true
}
return cell
}
虽然我已经收到了对第三方框架的引用,但我还没有收到任何关于如何使用我在问题中提供的代码实现它们的答案,或者甚至使用已经实现缓存机制的苹果的答案..我把问题放在问题中的原因是在答案中使用..谢谢。
答案 0 :(得分:4)
以下是集合视图单元格的示例:
import UIKit
let imageCache = NSCache<AnyObject, AnyObject>.sharedInstance
class myCell: UICollectionViewCell {
@IBOutlet public weak var myImageView: UIImageView?
private var imageUrlString: String?
private var downloadTask: URLSessionDownloadTask?
public var imageURL: URL? {
didSet {
self.downloadItemImageForSearchResult(imageURL: imageURL)
}
}
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
}
public func downloadItemImageForSearchResult(imageURL: URL?) {
if let urlOfImage = imageURL {
if let cachedImage = imageCache.object(forKey: urlOfImage.absoluteString as NSString){
self.myImageView!.image = cachedImage as? UIImage
} else {
let session = URLSession.shared
self.downloadTask = session.downloadTask(
with: urlOfImage as URL, completionHandler: { [weak self] url, response, error in
if error == nil, let url = url, let data = NSData(contentsOf: url), let image = UIImage(data: data as Data) {
DispatchQueue.main.async() {
let imageToCache = image
if let strongSelf = self, let imageView = strongSelf.myImageView {
imageView.image = imageToCache
imageCache.setObject(imageToCache, forKey: urlOfImage.absoluteString as NSString , cost: 1)
}
}
} else {
//print("ERROR \(error?.localizedDescription)")
}
})
self.downloadTask!.resume()
}
}
}
override public func prepareForReuse() {
self.downloadTask?.cancel()
myImageView?.image = UIImage(named: "ImagePlaceholder")
}
deinit {
self.downloadTask?.cancel()
myImageView?.image = nil
}
}
不要忘记为NSCache进行扩展 像这样:
import Foundation
extension NSCache {
class var sharedInstance: NSCache<NSString, AnyObject> {
let cache = NSCache<NSString, AnyObject>()
return cache
}
}
答案 1 :(得分:1)
使用NSCache和NSOperationQueue管理图像加载。在https://stackoverflow.com/a/12721899/5271191概述了该技术的好帖子(它的Objective-C,但Swift的技术是相同的。)
答案 2 :(得分:1)
我强烈建议您为UIImageView使用一个干净的原位替换/扩展,它将透明地管理图像的缓存,并避免维护操作队列等不必要的复杂性。
如果在内存缓存中满足您的需求 - 请查看 -
https://github.com/nicklockwood/AsyncImageView
如果你想要持久缓存,那么这个会做 -
https://github.com/rs/SDWebImage
HTH。
答案 3 :(得分:1)
您应该使用专门的框架。我不建议使用SDWebImage,它已经过时且不稳定。
看看这两个与iOS平台最新的库:
答案 4 :(得分:1)
我的collectionViewCell中有图像被提取和解析 通过NSURLRequest,我如何缓存这些图像,以便他们不必这样做 每一次出现/消失都会开始一个新的请求 查看?
URL loading system已经提供了缓存。看看the docs for NSURLCache。如果您所需的资源尚未充分缓存,则可能只需调整分配给应用程序的URL缓存的磁盘空间。
您还应该查看随资源返回的标头(缓存控制,过期等),以确保它们不会阻止缓存。 Here's a short tutorial on cache-related headers.
答案 5 :(得分:-1)
我使用swift 2创建了一个库来执行图像请求并对其进行缓存。试一试非常简单。
https://github.com/georgehadly/GHImageCaching
你所能做的就是这样,
request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField:"Content-Type")
如果您要删除所有缓存的图片
viewImg.getCachedImage("geo", URI: NSURL(string: "https://s-media-cache-ak0.pinimg.com/236x/8e/5a/98/8e5a98795dc2c5322cac97343a6cad6d.jpg")!) { (done) -> Void in
if(done){
// your extra
}
}