You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

NSInternalInconsistencyException:Animator已停止的偶发崩溃原因咨询

UIViewPropertyAnimator 已停止异常分析与解答

异常信息

libc++abi: terminating with uncaught exception of type NSException
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Animator <UIViewPropertyAnimator(0x600003f24200) [stopped] interruptible> is already stopped!'

触发代码

// other code up here that modifies offsetAnimator
...

// stop any current running animations on offset
if let offsetAnimator = offsetAnimator {
    offsetAnimator.stopAnimation(false) // 异常触发点
    offsetAnimator.finishAnimation(at: .end)
}

错误原因

UIViewPropertyAnimator的stopAnimation(_:)方法有严格的状态限制:仅能在动画处于.active状态(运行中或已暂停)时调用。如果动画已经处于.stopped或.inactive状态(动画已完成、已被强制停止或未启动),调用该方法会直接抛出NSInternalInconsistencyException异常。

为何异常仅偶发?

异常的偶发性源于动画状态的不确定性:

  • 代码中的offsetAnimator可能在进入if let判断块之后、调用stopAnimation之前,已经因其他逻辑切换到非.active状态。比如动画刚好在这个间隙自然完成,或者其他异步回调提前调用了stopAnimation/finishAnimation改变了状态。
  • 多线程干扰:如果有其他线程触发了动画状态变更(尽管UIKit操作应在主线程,但某些回调可能在非主线程间接修改状态),也会导致状态检查和实际调用之间出现不一致。

为什么连续调用两次stopAnimation不总是报错?

第一次调用stopAnimation(false)时,若动画处于.active状态,调用后动画会进入暂停的.active状态(而非直接变为.stopped),此时第二次调用stopAnimation(false)仍处于合法状态范围内,不会触发异常。

只有当第一次调用后,动画状态因系统内部延迟、额外回调等原因提前切换到.stopped/.inactive,第二次调用才会报错——这种场景出现概率较低,因此你观察到的是偶发错误。

解决方案

在调用stopAnimation前,先检查动画状态是否为.active,避免对已停止/完成的动画执行非法操作:

if let offsetAnimator = offsetAnimator, offsetAnimator.state == .active {
    offsetAnimator.stopAnimation(false)
    offsetAnimator.finishAnimation(at: .end)
}

同时建议规范offsetAnimator的生命周期管理:动画完成或停止后,及时将其置为nil,避免后续代码操作已失效的动画实例。

内容的提问来源于stack exchange,提问作者AlanSTACK

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 03:40:18