在CollectionView中(在tableviewCell内部)使用SDWebImage的疯狂内存问题

时间:2019-02-21 20:58:54

标签: ios swift out-of-memory sdwebimage image-caching

我无法弄清楚为什么我开始滚动带有SDWebImage填充的图像视图的集合视图时,我的应用程序的内存会迅速上升的原因。如果尚未下载,则可以暂时使用。但是一旦下载完每个图像,即使我什至触摸滚动条,应用程序ui也会变得无响应,并且内存飞速上升(超过1GB),不仅导致应用程序崩溃,而且整个操作系统崩溃并重新启动。

我有一个包含几个单元格的表格视图,其中一个具有可滚动的collectionview。我有一个数据对象,可用于填充collectionViewCell中的所有标签和图像。 cellForItem非常复杂(许多if语句和switch语句),因此我尝试将一些代码从那里移出,然后将其移到我在collectionViewCell中设置的用于容纳数据对象的属性的didSet方法中。然后,我只是将数据对象设置为itemForRow中的属性(在后台线程中),该属性触发了单个collectionViewCell的didSet方法来填充标签并使用sd_set_image方法设置图像。这是tableViewCell上的相关代码:

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
print(indexPath.row)
if itemStyle == .Grid {

  let cell = collectionView.dequeueReusableCell(withReuseIdentifier: self.resourceCellIdentifier, for: indexPath) as! ResourceCollectionViewCell
  cell.delegate = self
  cell.tag = indexPath.row

  if self.filter == Filter.Collections ||  self.resourceArray?[indexPath.row].actionContent == nil {
    let resource: ActionContentTemplate?
    if self.filter == Filter.Collections {
      resource = self.collectionResourceArray?[indexPath.row].actionContentTemplate
    } else {
      resource = self.resourceArray?[indexPath.row].actionContentTemplate
    }

    DispatchQueue.global(qos: .userInitiated).async {

      cell.dataObject = resource
    }
    return cell

  } else {.....

这是CollectionViewCell本身的didSet方法:

var dataObject: ActionContentTemplate? {
didSet {
  var cellRow: Int = 0

  if self.actionContentTemplate != nil {
    ....

    DispatchQueue.main.async {
      cellRow = self.tag

       .....

      switch self.actionContentTemplate?.contentTypeID?.uintValue {
      case ContentTypeVideo.rawValue,
           ContentTypeVideoRecording.rawValue,
           ContentTypeScreenRecording.rawValue:
        .......
      case ContentTypeAttachment.rawValue:


        let fileType = (self.actionContentTemplate?.contentFileName as NSString?)?.pathExtension.lowercased()
        var placeholderImage: UIImage

        if fileType == "pdf" {
          placeholderImage = UIImage(named: "pdf")!
        } else if fileType == "doc" {
          placeholderImage = UIImage(named: "doc")!
        } else if fileType == "docx" {
          placeholderImage = UIImage(named: "doc")!
        } else if fileType == "xls" {
          placeholderImage = UIImage(named: "xls")!
        } else if fileType == "xlsx" {
          placeholderImage = UIImage(named: "xls")!
        } else if fileType == "ppt" {
          placeholderImage = UIImage(named: "ppt")!
        } else if fileType == "pptx" {
          placeholderImage = UIImage(named: "ppt")!
        } else {
          placeholderImage = UIImage(named: "plain")!
        }

        if let urlString = self.actionContentTemplate?.thumbnailURL {
          let imageURL = URL(string: urlString)

          SDWebImageManager.shared().loadImage(with: imageURL, options: [.continueInBackground, .scaleDownLargeImages], progress: nil) { (image, data, err, cacheType, finished, url) in
              DispatchQueue.main.async {
                if cellRow == self.tag {

                self.activityIndicator?.stopAnimating()
                self.imageView.image = image
                UIAnimation.fadeTransitionImageView(self.imageView)
              }
            }
          }
                      }

        } else {
          DispatchQueue.main.async {

            self.activityIndicator?.stopAnimating()
            self.imageView.image = placeholderImage
          }
        }
        break
.....

由于sd_setimage方法也不起作用,因此我实际上切换到loadImage方法。

 SDWebImageManager.shared().loadImage(with: imageURL, options: [.continueInBackground, .scaleDownLargeImages], progress: nil) { (image, data, err, cacheType, finished, url) in
                  DispatchQueue.main.async {
                    if cellRow == self.tag {
//IF I COMMENT OUT THESE TWO LINES BELOW THE ISSUES STOP (I think it is only the self.imageView.image = image line that is causing issues)
         //           self.activityIndicator?.stopAnimating()
         //           self.imageView.image = image
                    UIAnimation.fadeTransitionImageView(self.imageView)
                  }
                }
              }

任何人都可以向我解释为什么会发生这种情况以及我可以采取哪些措施来解决它?

编辑-忘记将这些设置添加到问题的应用程序委托中

//Settings for image caching
  [[SDWebImageDownloader sharedDownloader] setShouldDecompressImages:NO];

  [[[SDImageCache sharedImageCache] config] setShouldDecompressImages:NO];
  [[[SDImageCache sharedImageCache] config] setShouldCacheImagesInMemory:NO];
  [[[SDImageCache sharedImageCache] config] setMaxCacheSize:1024 * 1024 * 100];
  [[[SDImageCache sharedImageCache] config] setMaxCacheAge:3600 * 24 * 7];
  [[SDImageCache sharedImageCache] setMaxMemoryCost:1024 * 1024 * 15];

1 个答案:

答案 0 :(得分:0)

结果显示缩略图相当大,使用此链接(iOS Swift: How to properly scale down an image?)将图像调整为imageView大小可以完全解决内存问题。但是,下载完图像后,滚动会有点混乱。...我认为将尽可能多的计算代码移至后台线程,并移出cellForItem会对此有所帮助,但我显然遗漏了一些东西。如果有人能指出正确的方向,那我将不胜感激,因为我一直在努力学习更多有关开发人员的知识。