我有一个详细的viewcontroller,它包含一个带有动画图像视图的重复轮播,如下所示:
func animateCarousel1(){
UIView.animate(withDuration: 1, delay: 3, options: .curveEaseInOut, animations:
//image animation
},completion: { (_) -> Void in
print("animation 1 complete")
self.animateCarousel2()
})
}
func animateCarousel2(){
UIView.animate(withDuration: 1, delay: 3, options: .curveEaseInOut, animations:
//image animation
},completion: { (_) -> Void in
print("animation 2 complete")
self.animateCarousel1()
})
}
在弹出这个视图并返回到父视图后,我看到在调试控制台中,这些函数继续在后台被重复,同时,无限地调用。
模拟器中的CPU使用率也会跃升至90%。
在弹出viewcontroller之前,我需要做一些deinit吗?我似乎无法绕过这一个。
答案 0 :(得分:1)
问题是即使动画结束也会调用完成块。所以有一些可能的解决方案:
检查完成处理程序的finished
参数:
func animateCarousel1() {
UIView.animate(withDuration: 1, delay: 3, options: .curveEaseInOut, animations: {
//image animation
}, completion: { finished in
print("animation 1 complete")
if finished { self.animateCarousel2() }
})
}
func animateCarousel2() {
UIView.animate(withDuration: 1, delay: 3, options: .curveEaseInOut, animations: {
//image animation
}, completion: { finished in
print("animation 2 complete")
if finished { self.animateCarousel1() }
})
}
使用不同的动画技术,不需要这些动画例程之间的循环引用,例如:
func animateCarousel() {
UIView.animateKeyframes(withDuration: 8, delay: 3, options: .repeat, animations: {
UIView.addKeyframe(withRelativeStartTime: 0, relativeDuration: 0.125) {
// animation 1
}
UIView.addKeyframe(withRelativeStartTime: 0.5, relativeDuration: 0.125) {
// animation 2
}
}, completion: nil)
}
答案 1 :(得分:1)
这有可能解决您可以看到此帖link here
的问题在deinit()控制器方法或viewDidDissapear()上使用,请尝试以下代码
deinit {
print("deinit \(NSStringFromClass(self.classForCoder).components(separatedBy: ".").last ?? "")") // print viewcontroller deallocated
self.view_for_remove_animations.layer.removeAllAnimations() // Forze delete animations
}
OR
override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)
print("viewDidDisappear \(NSStringFromClass(self.classForCoder).components(separatedBy: ".").last ?? "")") // print viewcontroller deallocated
self.view_for_remove_animations.layer.removeAllAnimations() // Forze delete animations
}
试一试,并发送反馈
答案 2 :(得分:1)
原因是在动画块中,你正在使用self的强引用,这就是为什么当你弹出这个viewcontroller时它的引用计数仍然不是0,因为ARC无法释放该视图控制器的引用。
有[weak self]
的概念。您可以像下面那样修改代码,然后在弹出后,您将无法在调试控制台中看到这些方法调用。原因:弱自我不会增加引用计数,ARC将能够删除对象的引用
func startAnimation() {
UIView.animate(withDuration: 0.4, animations: {[weak self] in
self?.animateView.frame = CGRect(x: 0, y: 0, width: 100, height: 100)
print("startAnimation")
}, completion: {[weak self]
finished in
self?.startAnimation2()
})
}
func startAnimation2() {
UIView.animate(withDuration: 0.4, animations: {[weak self] in
self?.animateView.frame = CGRect(x: 100, y: 0, width: 100, height: 100)
print("startAnimation2")
}, completion: {[weak self]
finished in
self?.startAnimation()
})
}