是否需为UIView动画添加DispatchQueue.main.async?iOS动画线程疑问
UIView动画是否需要包裹在DispatchQueue.main.async里?
核心原则:所有UI相关操作(包括动画)必须在主队列执行,要不要包裹取决于你当前代码的执行队列:
- 如果你的代码已经在主队列(比如视图控制器的
viewDidLoad、viewWillAppear,或者按钮点击、手势回调这类UI事件触发的方法),完全不需要额外包裹DispatchQueue.main.async,直接写动画代码就行。多余的主队列异步调用反而会让动画延迟一帧执行,没必要。 - 如果你的代码是在后台队列(比如网络请求回调、异步数据处理、全局队列的任务里),那必须把
UIView.animate代码包裹在DispatchQueue.main.async里。因为UIKit是线程不安全的,后台线程操作UI可能导致界面卡顿、动画失效甚至崩溃。
举两个实际场景的代码示例:
后台任务中必须包裹的正确写法
// 后台执行耗时数据处理 DispatchQueue.global().async { let targetFrame = self.calculateTargetFrame() // 切回主队列执行动画 DispatchQueue.main.async { UIView.animate(withDuration: Constant.selectionIndicatorAnimationTime) { self.selector.frame = targetFrame } } }
主队列中无需包裹的简化写法
// 比如在按钮点击事件里 @IBAction func onButtonTap(_ sender: UIButton) { let newFrame = CGRect(x: 0, y: 0, width: 200, height: 50) // 直接执行动画,当前已经在主队列 UIView.animate(withDuration: Constant.selectionIndicatorAnimationTime) { self.selector.frame = newFrame } }
总结:不确定当前队列的情况下,加上DispatchQueue.main.async不会出错,但如果明确在主队列,去掉更高效。
内容的提问来源于stack exchange,提问作者Nersifal Cronnus
相关产品推荐
相关产品推荐

