在计时器上使用UIView动画时的Swift内存问题

我在Xcode 6.1中使用Swift进行编码,并尝试创建一个简单的自动照片幻灯片,在照片之间具有交叉溶解效果。

我认为最好的实现是创建一个重复的NSTimer并调用一个选择器方法

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

当我在模拟器上运行时,程序会在每次照片淡入时分配更多内存,直到所有9张照片都消失,然后内存使用量变为450MB左右。 使用16GB内存的Mac上的模拟器运行时没问题。

但是当我在设备上运行时这是一个问题(在这种情况下是iPhone 6)。 系统给我内存警告,一些平滑过渡变得相当不稳定,最终应用程序崩溃。

所以我想我有3个问题:

  1. 为什么每个动画都使用这么多内存? 看起来每个动画平均分配大约50MB,我的图像每个不超过4MB。

  2. 为什么我的应用程序似乎在不再使用图像后保留内存? ARC不会自动释放它们吗?

  3. 有没有什么办法解决这一问题?

谢谢你的帮助!

正如@rdelmar所说,使用imageWithContentsOfFile: .

另外,我为您提供了一种不使用NSTimer()进行动画制作的替代方法,供您参考。

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

UIImageview可以为您创建这样的动画,而不必像您那样通过s计时器更改图像。

看看animationImages属性。