升级Xcode 14后App启动崩溃:UIButton dealloc异常修复咨询
问题现象
升级Xcode14后,App启动时直接崩溃,抛出NSInternalInconsistencyException异常,错误信息为:
Application circumvented Objective-C runtime dealloc initiation for
object
断言失败于-[UIButton dealloc](UIView.m:4628),崩溃触发在NIB加载视图控制器的流程中。
问题原因
该断言是Xcode14对应的UIKit版本新增的校验逻辑,目的是阻止绕过Objective-C引用计数机制直接调用dealloc,或者通过Method Swizzling非法篡改dealloc的正常调用流程。当UIButton的释放逻辑不符合Runtime规范时,就会触发这个断言。
修复方法
1. 排查并修正Method Swizzling代码
检查项目中是否对UIButton、UIView的dealloc方法做了方法替换:
- 搜索类似以下的swizzle代码:
Method originalDealloc = class_getInstanceMethod([UIButton class], @selector(dealloc)); Method swizzledDealloc = class_getInstanceMethod([UIButton class], @selector(custom_dealloc)); method_exchangeImplementations(originalDealloc, swizzledDealloc); - 修复方案:
- 优先替换监听时机:改用
willMoveToWindow:、didMoveToWindow:等方法来监听视图的生命周期,避免篡改dealloc; - 若必须保留swizzle,确保自定义的
dealloc中必须调用原实现,且绝对不能手动调用dealloc方法:- (void)custom_dealloc { // 自定义逻辑 [self custom_dealloc]; // 调用原dealloc实现,注意这里因为swizzle,实际调用的是系统的dealloc }
- 优先替换监听时机:改用
2. 删除手动调用dealloc的代码
OC中绝对禁止手动调用dealloc方法,所有对象的释放必须由Runtime通过引用计数自动触发。搜索项目中是否存在:
[myButton dealloc];
这类代码,直接删除,改为通过设置对象为nil来触发引用计数递减:
myButton = nil;
3. 排查第三方库兼容性
项目依赖的第三方UI库、工具库可能存在上述问题:
- 临时禁用第三方库,逐步排查定位到有问题的库;
- 查看库的更新日志,是否有Xcode14兼容修复,若有则升级到最新版本;
- 若库未更新,可自行修改库中的问题代码(比如移除非法的dealloc swizzle或手动调用)。
4. 清理缓存重新构建
- 执行
Product -> Clean Build Folder清理构建缓存; - 删除DerivedData目录(可通过
Xcode -> Settings -> Locations找到路径); - 重新构建项目,排除缓存导致的异常。
验证
修复后,在iPhone模拟器及真机上测试App启动流程,确认NIB加载过程中不再触发该崩溃。
内容的提问来源于stack exchange,提问作者sejn
相关产品推荐
相关产品推荐

