UIView.animate的completion闭包是否在主线程执行?
UIView.animate的completion闭包线程问题排查
问题背景
我实现了一个简单的popupView弹窗,最初的基础动画逻辑如下:
// Present if popup.superView != currentView { currentView.addSubview(popup) } UIView.animate(withDuration: 0.3, animations: { popup.alpha = 1 }) // Dismiss UIView.animate(withDuration: 0.3, animations: { popup.alpha = 0 }, completion: { popup.removeFromSuperview() })
实际运行时发现,若弹出(present)和关闭(dismiss)操作同时触发,新的弹出操作会被关闭逻辑的completion回调打断失效。因此新增animationCount计数变量优化逻辑,代码如下:
var animationCount: Int = 0 // Present if popup.superView != currentView { currentView.addSubview(popup) } animationCount += 1 UIView.animate(withDuration: 0.3, animations: { popup.alpha = 1 }, completion: { animationCount -= 1 // 注:原代码此处存在笔误,闭包结束应为}而非) ) // Dismiss animationCount += 1 UIView.animate(withDuration: 0.3, animations: { popup.alpha = 0 }, completion: { animationCount -= 1 if animationCount == 0 { popup.removeFromSuperview() } })
优化后逻辑运行表现符合预期,但存在一个疑问:在UIView.animate的completion闭包中读写animationCount变量是否会产生数据竞争?核心判断依据是:如果completion闭包运行在主线程,那么animationCount就不存在数据竞争问题,也不会出现弹窗无法从父视图移除的异常。
解答
结论非常明确:UIView.animate的animations闭包、completion闭包始终在主线程执行,你当前的计数方案不存在数据竞争问题。
- UIKit本身是线程不安全的框架,苹果官方要求所有UI相关操作必须在主线程执行,UIView动画作为UI核心能力,系统会自动将动画逻辑、完成回调全部调度到主线程运行,哪怕你在子线程调用
UIView.animate方法,回调也不会跑在子线程。 - 你的计数逻辑本身是成立的:只要保证所有触发present/dismiss时对
animationCount的+1操作、completion回调里的-1和移除视图判断都在主线程执行,就不会出现计数错乱、弹窗漏移除的问题。
修正后可直接使用的代码
你贴的优化代码存在两处语法/适配问题:一是present逻辑的completion闭包结尾笔误把}写成了),二是较新iOS版本的completion闭包会返回动画完成的布尔值参数,修正后代码如下:
var animationCount: Int = 0 // Present if popup.superview != currentView { currentView.addSubview(popup) } animationCount += 1 UIView.animate(withDuration: 0.3, animations: { popup.alpha = 1 }, completion: { _ in animationCount -= 1 }) // Dismiss animationCount += 1 UIView.animate(withDuration: 0.3, animations: { popup.alpha = 0 }, completion: { _ in animationCount -= 1 if animationCount == 0 { popup.removeFromSuperview() } })
额外提示:日常开发中所有触发弹窗弹出、关闭的操作都应该手动放在主线程调用,这是UIKit的基础开发规范,也能彻底避免极端时序下的逻辑异常。
内容的提问来源于stack exchange,提问作者sangyoonlee019
相关产品推荐
相关产品推荐

