Apple Silicon M1 Mac上原生运行iOS App访问视图控制器时出现_UIScrollerImp断言崩溃
崩溃根因定位
直接对照核心断言日志就能锁定问题:*** Assertion failure in -[_UIRegularOverlayScrollerImp setKnobProportion:], _UIScrollerImp.m:347 搭配触发的校验提示Invalid parameter not satisfying: !isnan(newKnobProportion),本质是内部滚动条渲染模块接收到了*非数值(NaN)*类型的滑块比例参数,触发了UIKit的内置断言崩溃。
这个问题不是你的业务代码逻辑错误——毕竟应用在iOS真机、iOS模拟器全链路运行正常,它是Apple Silicon M1刚推出时,iOS应用原生运行在Mac系统的适配层自带的原生Bug。
堆栈路径拆解
对照崩溃栈能完整还原触发流程:
- 崩溃发生在UINavigationController的视图转场过程中:当目标视图控制器被push进来、它的视图被添加到导航容器的视图层级、即将移动到窗口上显示时
- 系统会调用UIScrollView的
_updateScrollerImpsForcingReplacement:方法,为内部滚动条计算匹配的滑块比例值 - 在Mac端的UIKit适配链路里,这个滑块比例的计算公式存在除零漏洞:当ScrollView的视图高度/内容高度在布局尚未完成的瞬间为0时,比例计算的除法运算会直接返回NaN值
- 这个异常值被直接传入
_UIScrollerImp的实例方法,触发数值校验失败、抛出崩溃
你提到的“仅访问某一个特定VC时才崩溃”的表现,完全匹配这个Bug的触发特征:
- iOS真机、模拟器上的布局时序里,ScrollView的尺寸会在视图挂载到窗口前就完成AutoLayout计算,不会出现零尺寸的计算瞬间
- M1原生运行环境下,iOS视图的布局流程嵌入了AppKit的布局调度逻辑,时序差导致了零尺寸窗口下的除零运算,最终触发崩溃
- 日志开头的
[AXRuntimeCommon] Unknown client: MyApp是完全无关的无障碍模块告警,仅代表辅助功能框架没有识别到运行在Mac上的iOS应用标识,和崩溃逻辑没有关联
当时社区通用的临时规避方案
在系统补丁修复前,开发者通常通过几个方式绕开这个崩溃:
- 代码创建UITableView、UICollectionView等滚动类视图时,不设置初始
frame = .zero,哪怕后续靠AutoLayout约束调整尺寸,也给视图一个非零的初始frame值 - 视图控制器生命周期早期,给内部ScrollView的bounds和contentSize设置非零的兜底值,避免除零计算
- 这个Bug在macOS 11.2版本之后被Apple官方修复,后续系统版本上已经不会复现同类问题
内容的提问来源于stack exchange,提问作者de.
相关产品推荐
相关产品推荐

