Lookin点击刷新后app闪退问题排查
一句话真因
UI层存在频繁添加删除子View的逻辑,Lookin或者xcode查看图层时,相应的子view刚好释放,对已释放的UI对象发送消息获取UI相关信息时,出现野指针闪退 (也不能说是代码的问题或者Lookin的问题,只能说两个方面协调的有点小问题)
起因
最近接触到HT的项目,熟悉代码过程中有遇到在某些页面停留时,点击Lookin刷新按钮后,页面没有完全加载完,app就闪退,极其影响效率。(Xcode查看图层也有类似的问题)
Lookin的弹框提示

Lookin里会出现一个弹框,因为涉及的页面有些绘制的图片,弹框提示文案也有可能是某个view尺寸过大导致的。问了一下熟悉项目的开发,意思也是可能是页面比较复杂,图表过大导致的。🤔,好像不对呀,闪退时报错的提示明明是野指针呀…以前项目每个页面至少2~3千个子view,Lookin使用都是正常的,现在有时只有1千个子view,Lookin刷新还是会闪退,应该不是子view数量过多的问题
App闪退时的提示
排查过程
1、注释代码排查阶段
- 先缩小一下排查范围吧,试了一下,基本上是在有图表绘制的详情页才会出现Lookin刷新闪退的问题
- 查找相应的UI层级,留下关键的UI进行排查,注释掉其它的代码,一通折腾后,发现好像真的和图表绘制有关
- 在图表UI组件相关的组件内各种注释,又是一通折腾,貌似问题是偶现的,不是必现,怪了,不清楚到底是哪里出了问题
2、内存泄漏排查
- 看了一下,没啥有效的信息,内存泄漏是对象未释放,现在是野指针,是对象释放了,白折腾了
3、野指针排查
- 项目有点问题,instuments运行几秒钟就挂了,没法有效的进行排查,奇怪了,后续再确认为啥不能用吧 // TOTO
- 勾选scheme->Diagnostics->Memory Management-> Zombie Objects,排查一下僵尸对象
闪退详情
- 这个时候点击主线程,往上找堆栈最上面,能看到的确是野指针的问题,是向已经释放的对象发送了消息,导致了闪退
- 猜想是Lookin点击刷新的瞬间有对象刚好释放了,导致Lookin对那个对象发送消息获取UI相关信息的时候出现了闪退
- 看闪退详情的截图,是否可以通过这里拿到将要释放对象的类名呢,或者内存地址,查询了一下,在这种场景下,LLDB上输入register read rbx,可以打印出释放对象的16进制地址
- 如何才能拿到最近释放的对象呢,想了想,可以通过hook对象的dealloc方法,把最近释放的对象地址都打印出来,一开始hook的是NSObject对象,app启动时就卡着不动了,可能是释放的对象太多了;想了想,换个hook对象,只hook UIView的dealloc方法吧,有效果,程序能跑起来了
- 跑起程序,在相应界面Lookin刷新后,通过寄存处中的地址和打印的释放对象的地址进行比对,可以确认到底是哪些类出了问题
4、修复过程
有3个地方有问题,代码逻辑的共性都是存在频繁刷新UI,在刷新时,将原来的子view从父view上移除,将对象置为nil,然后重新创建对象添加到view上
大概分3种情况规避问题:
- 添加判断条件,减少移除添加逻辑执行的次数
- 添加debug宏判断,如果时是测试环境则延时0.5秒再将对象置为nil
- 在scrollView内频繁添加移除子view的场景,这个暂时没找到简单的办法,只能通过使用UITableView或者UICollectionView重写,如果有更好的办法,请通知我,谢谢
看github上也有issue反馈一刷新就闪退,怀疑也是类似的问题
后续
TODO: 立Flag
- 后续准备学习一下Lookin的代码
- 了解一下为啥instuments在这个项目没法用
- 汇编熟悉一下
Written on July 1, 2025