ImageSlideshow icon indicating copy to clipboard operation
ImageSlideshow copied to clipboard

Memory issue with SDWebImageSource

Open georgehl opened this issue 7 years ago • 5 comments

I posted an issue previously #214 although I think I've narrowed down the problem. We have a tableview with an imageslideshow inside the cell. When the tableview scrolls memory jumps from 30mb to 160mb and doesn't ever go back down.

This is our code for setting the imageslideshow: let imageSource = [SDWebImageSource(urlString: post.imageUrl1)!, ImageSource(image: UIImage(named: "Beach")!)] self.postSlideshow.setImageInputs(imageSource as! [InputSource])

Replacing the above code with: let imageSource = [ImageSource(image: UIImage(named: "Beach")!), ImageSource(image: UIImage(named: "Beach")!)] self.postSlideshow.setImageInputs(imageSource) fixes the memory problem.

Notes: we don't use currentPageChanged, willBeginDragging or didEndDecelerating closures. The image urls we use for SDWebImageSource have images under 500kb in size

georgehl avatar Nov 29 '17 15:11 georgehl

I also have this issue.

       var inputs = [SDWebImageSource]()
        if let imageURLStrings = associatedProperty.imageURLStrings {
            for imageString in imageURLStrings {
                let input = SDWebImageSource.init(urlString: imageString, placeholder: #imageLiteral(resourceName: "property-no-image"))
                inputs.append(input!)
            }
        }
        slideShow.setImageInputs(inputs)

can't seem to find a way to stop the leak

The pod works fantastic on individual screens, or callouts!

However once it's introduced into a tableview/tableview cell, it starts a massive memory leak which eventually causes the device to disconnect.

Is there a specific way to use this pod in a tableView? I just have cells with some text underneath, and a iamgeSlideShow above that.

Viktorfalkner avatar Dec 29 '17 22:12 Viktorfalkner

I have same issue with memory leaks when use imageSlideShow in tableView

spase84 avatar Jan 08 '18 10:01 spase84

Same problem here, 12 jpg image 3MB each. Memory usage over 500MB and application crashes

CarioniStefano avatar Jun 17 '19 18:06 CarioniStefano

I faced this too and found a workaround, just limit RAM usage by SDWebImage by specifying cache size, for example to 15 MB or whatever you're found reasonable for you:

SDImageCache.shared().maxMemoryCost = 15 * 1024 * 1024

klassneckii avatar Dec 05 '19 08:12 klassneckii

I end with the lots of images more than expectation , I think I stuck in for loop , can someone help me?

import UIKit
import AVFoundation
import ImageSlideshow

class MediaDetailsTableViewCell: UITableViewCell , ASAutoPlayVideoLayerContainer{

   var imageData = [SDWebImageSource]()
    
    @IBOutlet var slideshow: ImageSlideshow!
    
        @IBOutlet weak var fullNameOnFeed : UILabel!
        @IBOutlet weak var academyNameOnFeed : UILabel!
        @IBOutlet weak var pictureUrlOnFeed : UIImageView!
//        @IBOutlet weak var feedImageOnFeed : UIImageView!
        @IBOutlet weak var hashtagOnFeed : UILabel!
        @IBOutlet weak var sessionNameOnFeed : UILabel!
        @IBOutlet weak var sessionDetailsOnFeed : UILabel!
    
    var playerController: ASVideoPlayerController?
      var videoLayer: AVPlayerLayer = AVPlayerLayer()
      var videoURL: String? {
          didSet {
              if let videoURL = videoURL {
                  ASVideoPlayerController.sharedVideoPlayer.setupVideoFor(url: videoURL)
              }
              videoLayer.isHidden = videoURL == nil
            videoLayer.frame = self.frame
            videoLayer.videoGravity = AVLayerVideoGravity.resizeAspectFill
            videoLayer.videoGravity = .resizeAspectFill
            videoLayer.frame = slideshow.bounds
           
            
          }
      }
        var item: MediaDetails? {
            didSet{
                guard let item = item  else {
                return
                }
                if let fullNameOnFeed = fullNameOnFeed {
                    fullNameOnFeed.text = item.fullName
                }
                if let academyNameOnFeed = academyNameOnFeed {
                    academyNameOnFeed.text = item.academyName
                }
                if let hashtagOnFeed = hashtagOnFeed {
                    hashtagOnFeed.text = item.hashtag
                }
                if let sessionNameOnFeed = sessionNameOnFeed {
                    sessionNameOnFeed.text = item.sessionName
                }
                if let sessionDetailsOnFeed = sessionDetailsOnFeed {
                    sessionDetailsOnFeed.text = item.sessionDetails
                }
                if let pictureUrl = item.pictureUrl {
                    pictureUrlOnFeed?.image = UIImage(named: pictureUrl)
                }
                if item.videoURL != nil {
                    if let videoLayerURL = item.videoURL {
                        self.videoURL = videoLayerURL
                        self.configureCell(imageUrl: nil, videoUrl: videoLayerURL)
                        print("video is \(videoLayerURL)")
                    }
                }
                    
                else {
                let itemImages = item.feedImage
                if itemImages.count > 0 {
                    for url in itemImages {
                        let image = SDWebImageSource(urlString: url.images ?? "")
                            if let SDURL = image{
                                imageData.append(SDURL)
                        }
                        }
                        self.slideshow.setImageInputs(imageData)
                       
                    }
                 self.configureCell(imageUrl: imageData, videoUrl: nil)
                
                }
            }
        }
    
    
    
  
    
    
        override func awakeFromNib() {
            super.awakeFromNib()
            videoLayer.backgroundColor = UIColor.clear.cgColor
            videoLayer.videoGravity = AVLayerVideoGravity.resize
            videoLayer.frame = slideshow.bounds
//            let tap = UITapGestureRecognizer(target: self, action: #selector(didTappedOnVideo))
//            videoLayer.addSublayer(tap)
            let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(imageTapped(tapGestureRecognizer:)))
            slideshow.isUserInteractionEnabled = true
            slideshow.addGestureRecognizer(tapGestureRecognizer)
            
            
            slideshow.layer.addSublayer(videoLayer)
            selectionStyle = .none
            
            
            //////
            slideshow.slideshowInterval = 5.0
            slideshow.pageIndicatorPosition = .init(horizontal: .center, vertical: .under)
            slideshow.contentScaleMode = UIViewContentMode.scaleAspectFill

            let pageControl = UIPageControl()
            pageControl.currentPageIndicatorTintColor = UIColor.lightGray
            pageControl.pageIndicatorTintColor = UIColor.black
            slideshow.pageIndicator = pageControl

            // optional way to show activity indicator during image load (skipping the line will show no activity indicator)
            slideshow.activityIndicator = DefaultActivityIndicator()
            slideshow.delegate = self as? ImageSlideshowDelegate

            // can be used with other sample sources as `afNetworkingSource`, `alamofireSource` or `sdWebImageSource` or `kingfisherSource
           
          

            let recognizer = UITapGestureRecognizer(target: self, action: #selector(MediaDetailsTableViewCell.didTap))
            slideshow.addGestureRecognizer(recognizer)
            
        }
    
    @objc func imageTapped(tapGestureRecognizer: UITapGestureRecognizer)
    {
        let _ = tapGestureRecognizer.view as! UIImageView
        print("tappedHo rha h")
        ASVideoPlayerController.sharedVideoPlayer.shouldPlay.toggle()
        // Your action
    }
    
    @objc func didTap(){
        
    }
    
    func configureCell(imageUrl: [SDWebImageSource]?,
                          videoUrl: String?) {
        guard let sdd = imageUrl else { return}
        self.slideshow.setImageInputs(sdd)
           self.videoURL = videoUrl
       }
        static var nib:UINib {
            return UINib(nibName: identifier, bundle: nil)
        }
       static var identifier: String {
            return String(describing: self)
        }
        override func setSelected(_ selected: Bool, animated: Bool) {
            super.setSelected(selected, animated: animated)
        }
    override func prepareForReuse() {
        super.prepareForReuse()
    }
    override func layoutSubviews() {
        super.layoutSubviews()
        let horizontalMargin: CGFloat = 20
        let width: CGFloat = slideshow.bounds.width
        let height: CGFloat = slideshow.bounds.height
        videoLayer.frame = CGRect(x: 0, y: 0, width: width, height: height)
               
    }
    
    func visibleVideoHeight() -> CGFloat {
            let videoFrameInParentSuperView: CGRect? = self.superview?.superview?.convert(slideshow.frame, from: slideshow)
                  guard let videoFrame = videoFrameInParentSuperView,
                      let superViewFrame = superview?.frame else {
                       return 0
                  }
                  let visibleVideoFrame = videoFrame.intersection(superViewFrame)
                  return visibleVideoFrame.size.height
       }
}

I faced this too and found a workaround, just limit RAM usage by SDWebImage by specifying cache size, for example to 15 MB or whatever you're found reasonable for you:

SDImageCache.shared().maxMemoryCost = 15 * 1024 * 1024

pratikgajbhiye222 avatar Jul 20 '20 20:07 pratikgajbhiye222