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

iOS 16下ViewController dealloc崩溃问题(Xcode14升级后出现)

Xcode 14下登录后偶发僵尸对象崩溃排查方案

问题背景

  • 应用在iOS 15 + Xcode 13环境运行正常,切换到Xcode 14后,登录后出现偶发崩溃
  • 已开启僵尸对象检测:操作路径为 Edit Schemes -> Diagnostics,勾选Zombie objects选项

崩溃日志

Thread 0 Crashed:
0   libobjc.A.dylib                 0x00000001b4a1e820 objc_msgSend + 32
1   UIKitCore                       0x00000001bdbe74a4 -[UIViewController dealloc] + 772 (UIViewController.m:3102)
2   UIKitCore                       0x00000001bdbe50cc -[UINavigationController dealloc] + 308 (UINavigationController.m:786)
3   CoreFoundation                  0x00000001bb9e2734 __RELEASE_OBJECTS_IN_THE_ARRAY__ + 116 (NSCollectionAux.h:70)
4   CoreFoundation                  0x00000001bb981b94 -[__NSFrozenArrayM dealloc] + 124 (NSCopyOnWrite.h:229)
5   UIKitCore                       0x00000001be1539ec -[UIMoreListController .cxx_destruct] + 76 (UIMoreListController.m:58)
6   libobjc.A.dylib                 0x00000001b4a1e0a4 object_cxxDestructFromClass(objc_object*, objc_class*) + 116 (objc-class.mm:456)
7   libobjc.A.dylib                 0x00000001b4a22e00 objc_destructInstance + 80 (objc-runtime-new.mm:8628)
8   libobjc.A.dylib                 0x00000001b4a2c4fc _objc_rootDealloc + 80 (NSObject.mm:2138)
9   UIKitCore                       0x00000001bdbe78d8 -[UIResponder dealloc] + 124 (UIResponder.m:184)
10  UIKitCore                       0x00000001bdbe75dc -[UIViewController dealloc] + 1084 (UIViewController.m:3133)
11  libobjc.A.dylib                 0x00000001b4a1e0a4 object_cxxDestructFromClass(objc_object*, objc_class*) + 116 (objc-class.mm:456)
12  libobjc.A.dylib                 0x00000001b4a22e00 objc_destructInstance + 80 (objc-runtime-new.mm:8628)
13  libobjc.A.dylib                 0x00000001b4a2c4fc _objc_rootDealloc + 80 (NSObject.mm:2138)
14  UIKitCore                       0x00000001bdbe78d8 -[UIResponder dealloc] + 124 (UIResponder.m:184)
15  UIKitCore                       0x00000001bdbe75dc -[UIViewController dealloc] + 1084 (UIViewController.m:3133)
16  UIKitCore                       0x00000001bdbe50cc -[UINavigationController dealloc] + 308 (UINavigationController.m:786)
17  libobjc.A.dylib                 0x00000001b4a1e1d4 AutoreleasePoolPage::releaseUntil(objc_object**) + 196 (NSObject.mm:938)
18  libobjc.A.dylib                 0x00000001b4a21bdc objc_autoreleasePoolPop + 256 (NSObject.mm:2186)
19  UIKitCore                       0x00000001bdb87444 -[_UIAfterCACommitBlock run] + 92 (_UIAfterCACommitQueue.m:155)
20  UIKitCore                       0x00000001bdb87364 -[_UIAfterCACommitQueue flush] + 168 (_UIAfterCACommitQueue.m:228)
21  UIKitCore                       0x00000001bdb87278 _runAfterCACommitDeferredBlocks + 496 (UIApplication.m:3249)
22  UIKitCore                       0x00000001bda25ee4 _cleanUpAfterCAFlushAndRunDeferredBlocks + 108 (UIApplication.m:3213)
23  UIKitCore                       0x00000001bdee4608 _UIApplicationFlushCATransaction + 72 (UIApplication.m:3290)
24  UIKitCore                       0x00000001be034e00 _UIUpdateSequenceRun + 84 (_UIUpdateSequence.mm:114)
25  UIKitCore                       0x00000001be698944 schedulerStepScheduledMainSection + 144 (_UIUpdateScheduler.m:1015)
26  UIKitCore                       0x00000001be697ea0 runloopSourceCallback + 92 (_UIUpdateScheduler.m:1116)
27  CoreFoundation                  0x00000001bba4c208 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 28 (CFRunLoop.c:1957)
28  CoreFoundation                  0x00000001bba58864 __CFRunLoopDoSource0 + 176 (CFRunLoop.c:2001)
29  CoreFoundation                  0x00000001bb9dd6c8 __CFRunLoopDoSources0 + 244 (CFRunLoop.c:2038)
30  CoreFoundation                  0x00000001bb9f31c4 __CFRunLoopRun + 828 (CFRunLoop.c:2953)
31  CoreFoundation                  0x00000001bb9f84dc CFRunLoopRunSpecific + 612 (CFRunLoop.c:3418)
32  GraphicsServices                0x00000001f6c5835c GSEventRunModal + 164 (GSEvent.c:2196)
33  UIKitCore                       0x00000001bdd8437c -[UIApplication _run] + 888 (UIApplication.m:3773)
34  UIKitCore                       0x00000001bdd83fe0 UIApplicationMain + 340 (UIApplication.m:5363)

排查思路与方案

从崩溃栈分析,崩溃属于僵尸对象访问(即调用了已被释放对象的方法),核心触发点在UIMoreListController和UINavigationController的释放流程中,结合Xcode14的环境变化,可从以下方向排查:

1. 检查导航控制器的内存管理

  • 排查自定义UINavigationController的dealloc方法,确认是否存在调用已释放对象的逻辑,比如未清空的代理、block或KVO监听
  • 检查是否存在循环引用:比如子控制器通过强引用持有导航控制器,导致对象无法正常释放

2. 排查TabBar相关逻辑

  • 登录后跳转TabBar时,是否对UIMoreListController(TabBar默认的“更多”页面控制器)做了自定义修改,比如修改导航栏、添加子控制器时的内存处理不当
  • 确认TabBar控制器的子控制器数组是否被意外修改或提前释放

3. 适配Xcode14的编译变化

  • Xcode14默认启用了更严格的ARC规则,检查之前被ARC兼容的内存问题是否现在触发崩溃
  • 确认是否使用了iOS16+的新API但未做版本判断,导致iOS15环境下出现内存异常

4. 强化调试手段

  • 开启Malloc Stack Logging:在Edit Schemes -> Diagnostics中勾选Malloc Stack,重现崩溃后用malloc_history命令查看对象的分配/释放完整栈
  • 手动设置NSZombieEnabled环境变量:在Scheme的Environment Variables中添加NSZombieEnabled=YES,崩溃时会打印具体被重复释放的对象信息
  • 在关键控制器的dealloc方法中添加日志,跟踪对象释放顺序是否符合预期

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 12:37:56