Swift Memory Issues when using UIView Animation on a Timer

时光总嘲笑我的痴心妄想 提交于 2020-01-03 04:45:09

问题


I'm coding with Swift in Xcode 6.1 and trying to create a simple automatic photo slideshow with a cross-dissolve effect between photos.

I figured the best implementation would be to create a scheduled NSTimer that repeats and calls a selector method

@IBOutlet var backgroundImageView: UIImageView!

override func viewDidLoad() {
    super.viewDidLoad()

    backgroundImageView.image = UIImage(named: "1.jpg")

    let backgroundImageTimer = NSTimer.scheduledTimerWithTimeInterval(
        5.0, 
        target: self, 
        selector: "cycleBackgroundImages", 
        userInfo: nil, 
        repeats: true)
}


// Cycling through 9 different photos titled 1.jpg, 2.jpg, ..., 9.jpg
var currentPhotoID = 1
func cycleBackgroundImages() {
    if currentPhotoID < 9 { currentPhotoID++ }
    else { currentPhotoID = 1 }

    let toImage = UIImage(named: "\(currentPhotoID).jpg")
    UIView.transitionWithView(
        self.backgroundImageView, 
        duration: 2.0, 
        options: .TransitionCrossDissolve, 
        animations: { self.backgroundImageView.image = toImage }, 
        completion: nil
     })
}

When I run on the simulator, the program allocs more memory each time a photo is faded in until all 9 photos are faded through and then the memory usage flattens out at around 450MB. That's no problem when running using the simulator on my Mac with 16GB of memory.

But it is a problem when I run on the device (iPhone 6 in this case). The system gives me memory warnings, some of the smooth transitions become fairly choppy, and eventually the application crashes.

So I guess I have 3 questions:

  1. Why does each animation use so much memory? It looks like each animation allocs maybe around 50MB on average and my images are each no larger than 4MB.

  2. Why does my app seem to hold on to the memory after the images are no longer used? Doesn't ARC free them automatically?

  3. Is there any way to fix this?

Thanks for your help!


回答1:


As @rdelmar said, use imageWithContentsOfFile:.

In addition, I provide you an alternative way to do the animation without using a NSTimer(), for your reference.

class ViewController: UIViewController {
        @IBOutlet var backgroundImageView: UIImageView!

        override func viewDidLoad() {
                super.viewDidLoad()

                let path = NSBundle.mainBundle().pathForResource("1", ofType: "jpg")
                backgroundImageView.image = UIImage(contentsOfFile: path!)

                cycleBackgroundImages()
        }


        // Cycling through 9 different photos titled 1.jpg, 2.jpg, ..., 9.jpg
        var currentPhotoID = 1
        func cycleBackgroundImages() {
                if currentPhotoID < 9 { currentPhotoID++ }
                else { currentPhotoID = 1 }

                CATransaction.begin()
                CATransaction.setAnimationDuration(2.0)
                CATransaction.setCompletionBlock {
                        let delay = dispatch_time(DISPATCH_TIME_NOW, Int64(5 * NSEC_PER_SEC))
                        dispatch_after(delay, dispatch_get_main_queue()) {
                                self.cycleBackgroundImages()
                        }
                }

                let transition = CATransition()
                backgroundImageView.layer.addAnimation(transition, forKey: kCATransition)
                let path = NSBundle.mainBundle().pathForResource("\(currentPhotoID)", ofType: "jpg")
                backgroundImageView.image =  UIImage(contentsOfFile: path!)

                CATransaction.commit()
        }
}



回答2:


UIImageview can create such animations for you without having to go through and change the images with s timer as you've done.

Have a look at the animationImages property.



来源:https://stackoverflow.com/questions/26911663/swift-memory-issues-when-using-uiview-animation-on-a-timer

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!