ios - 在 Swift 的 collectionViewCell 中缓存图像?

标签 ios swift caching parse-platform uicollectionviewcell

我的 collectionViewCell 中有图像是通过 NSURLRequest 获取和解析的,我该如何缓存这些图像,这样它们就不必在每次 View 出现/消失时都启动新请求?

这是我获取图像的代码:

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
    }

虽然我收到了对第三方框架的引用,但我还没有收到任何关于如何使用我在问题中提供的代码来实现它们的答案,甚至没有收到使用苹果已经实现的缓存机制的答案。原因我把代码放在问题中是为了在答案中使用。谢谢。

最佳答案

这是您的 Collection View 单元格的示例:

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
  }
}

关于ios - 在 Swift 的 collectionViewCell 中缓存图像?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32577207/

相关文章:

ios - 如何在 UITextField 周围添加可点击标签

java - 使用 Hazelcast/Redis 满足数据库支持的缓存需求

ios - 为什么UIWindow添加UIGestureRecognizer后iPad无响应?

ios - 如何知道 enumerateTags 函数何时完成?

ios - Swift 中的 "is"关键字

ios - 无法修复 "Could not find or use auto-linked library "

ios - Swift - 覆盖 tableview 函数 - 方法不会覆盖其父类(super class)中的任何方法

caching - 在 Ember Octane 中缓存的最佳方法

Symfony2 : clear cache don't generate required file EntityManager_XXXX. php(用于 Doctrine )

objective-c - 在我的 UITableView 上放置渐变以显示单元格