nicklockwood / iCarousel

A simple, highly customisable, data-driven 3D carousel for iOS and Mac OS
http://www.charcoaldesign.co.uk/source/cocoa#icarousel
Other
11.99k stars 2.58k forks source link

Memory consumption issue with hundreds of views #879

Open renatoDutraSilva opened 5 years ago

renatoDutraSilva commented 5 years ago

Hi, I would like to thank Nicklockwood for publishing this work. extremely helpful and well put together. I have noticed the repository has not been updated for quite a while but still, I'll try to post this in an attempt to get some kind of help.

I've come across a memory consumption issue when using UIImages as my return view in viewForItemAt.

I have an image index and I am returning a UIImageVIew for each call of the method. If reuse view is available, I'll use it instead. So with the help of counters I can see that iCarousel creates 60 new views at first and then always reuses them. So how come my memory consumption goes through the roof ?

Here is my viewForItemAt:

func carousel(_ carousel: iCarousel, viewForItemAt index: Int, reusing view: UIView?) -> UIView {

        let screenSize = UIScreen.main.bounds
        let screenWidth = screenSize.width
        let screenHeight = screenSize.height
        let width: CGFloat = 0.5 * screenWidth
        let height: CGFloat = 0.2 * screenHeight

        if let view = view as? UIImageView {
            imageView = view
            countReused += 1
            print("Reused cells:")
            print(countReused)
        }else{
            count += 1
            print("New cells:")
            print(count)
            imageView.frame = CGRect(x: 0, y: 0, width: width, height: height)
            imageView.contentMode = .scaleToFill
            let shadowSize: CGFloat = 20
            let shadowDistance: CGFloat = 0
            let contactRect = CGRect(x: -shadowSize, y: height - (shadowSize * 0.4) + shadowDistance, width: width + shadowSize * 2, height: shadowSize)
            imageView.layer.shadowPath = UIBezierPath(ovalIn: contactRect).cgPath
            imageView.layer.shadowRadius = 5
            imageView.layer.shadowOpacity = 0.4

            imageView.layer.borderWidth = 1
            imageView.layer.borderColor = UIColor(red:0, green:0, blue:0, alpha: 1).cgColor
        }

        imageView.image = images[index]  
        return imageView
    }

I should add that "imageView" is a class property

Thank you!

nicklockwood commented 5 years ago

Your memory consumption is probably due to the images rather than the views.

It looks like you are storing UIImages in an array so each time you display an image for the first time, iOS will decode the image (which requires much more memory per image than the compressed image size) and then keep it indefinitely.

I suggest you take a look at some of the image-based examples in the iCarousel Examples folder, which use more advanced image caching strategies.