近期项目中频繁报出 Attempt to mutate immutable object with deleteCharactersInRange:CoreFoundation ___exceptionPreprocess
的错误, 整个项目的崩溃率一度上升到了 0.5%....
9月正值用户暴增的时期,这个崩溃率简直吓 shi 我们...
具体涉及到的崩溃有几个:
- 所有的 包含 UITextField 的 AlertView 弹框(无论是自定义的还是系统的), 大多数 plus 崩溃
- 在 UITextView 使用 系统键盘的语音输入必崩
- UICollectionView 中报出 "cell 的高度或宽度必须小于 collectionView 的高度或宽度(英文描述记不清了)" 的警告的 release 版崩溃(大多是 plus).(这里可以打 symbol break: UICollectionViewFlowLayoutBreakForInvalidSizes)
Bugly 捕获的 log 都是Attempt to mutate immutable object with deleteCharactersInRange
, 没有具体的定位...主要是错误还很难重现, 各种操作都没法根治这个问题,很纠结.
在浏览各种版本的崩溃统计中,我们发现类似崩溃开始出现在 4.5.2 版本,我们去 TestFlight 下载了4.5.1运行发现语音输入没有崩溃...所以大致知道了出问题的版本,这样搜索的范围就笑了, 开始我们浏览所有 gitlab 的提交记录去寻找,我们初步的猜想造成 crash 有以下几个可能:
- 对 UIScrollView 添加了什么 extension/category 做成了全局的影响
- 对 UITextView 添加了什么 extension/category 做成了全局的影响
- 对键盘做了什么处理
所以我们都是从历史所有的对基础库的修改进行查找....然后已经迭代了是几个小版本,一个大版本过去了将近两个月,范围虽然缩小了但还是大海捞针...
辗转各种查询,发现问题版本我们以 framework 的形式引入了子公司的项目,且是 oc 项目(我们主项目主体是 swift)...然后我们联系了那边的同事让他以他们的项目重现 bug 看能不能定位到具体位置...(锅终于甩出去了><)
事实结果也确实是他们的问题,他们之前就有这个 bug...但他们不知道重现方式, 最后根据这句堆栈信息[NSString stringWithFormat:]
查询到 他们重写了 UIVIew 的- (NSString *)description
方法
- (NSString *)description {
return [NSString stringWithFormat:@"%@,%p,%@", NSStringFromClass([self class]), self, NSStringFromCGRect(self.frame)];
}
所以的崩溃都是在系统调用到 description
方法时引起的
真的是...我们完全没有重视堆栈信息里面 [NSString stringWithFormat:]
和 [UIScrollview description]
, 毕竟乍看这两句你完全不知道如何去查询问题
至此问题得到解决, 新版本中也没有报出相关的错误了.
这里,我完全不知道在这么底层对系统方法进行重写的出发点是什么...仅仅是为了打印描述信息更详细吧.对这种全局的系统方法重写真的是要谨慎,特别是团队里面其他人还不知道...
网友评论