iOS 16.3.1及以上SwiftUI应用注销按钮间歇性崩溃求助
SwiftUI注销按钮iOS 16.3+/16.4+间歇性崩溃解决方案建议
我开发的SwiftUI应用中,个人资料标签页设有注销按钮,在iOS 16.3.1或16.4.1版本点击该按钮会出现间歇性崩溃,但iOS 15与iOS 16.1.1版本无此问题。以下是主线程的崩溃日志:
Exception Type: EXC_BAD_ACCESS (SIGSEGV) Exception Subtype: KERN_INVALID_ADDRESS at 0x0000000000000010 Exception Codes: 0x0000000000000001, 0x0000000000000010 VM Region Info: 0x10 is not in any region. Bytes before following region: 68719476720 REGION TYPE START - END [ VSIZE] PRT/MAX SHRMOD REGION DETAIL UNUSED SPACE AT START ---> commpage (reserved) 1000000000-7000000000 [384.0G] ---/--- SM=NUL ...(unallocated) Termination Reason: SIGNAL 11 Segmentation fault: 11 Terminating Process: exc handler [1481] Triggered by Thread: 0 Thread 0 name: Dispatch queue: com.apple.main-thread Thread 0 Crashed: 0 libobjc.A.dylib 0x1ba38e820 objc_msgSend + 32 1 UIKitCore 0x1c354f4a4 -[UIViewController dealloc] + 772 2 UIKitCore 0x1c354d0cc -[UINavigationController dealloc] + 308 3 UIKitCore 0x1c37d5bbc -[_UISplitViewControllerColumnContents .cxx_destruct] + 44 4 libobjc.A.dylib 0x1ba38e0a4 object_cxxDestructFromClass(objc_object*, objc_class*) + 116 5 libobjc.A.dylib 0x1ba392e00 objc_destructInstance + 80 6 libobjc.A.dylib 0x1ba39c4fc _objc_rootDealloc + 80 7 CoreFoundation 0x1c130b26c cow_cleanup + 168 8 CoreFoundation 0x1c1343538 -[__NSDictionaryM dealloc] + 148 9 libobjc.A.dylib 0x1ba38e0a4 object_cxxDestructFromClass(objc_object*, objc_class*) + 116 10 libobjc.A.dylib 0x1ba392e00 objc_destructInstance + 80 11 libobjc.A.dylib 0x1ba39c4fc _objc_rootDealloc + 80 12 libobjc.A.dylib 0x1ba38e0a4 object_cxxDestructFromClass(objc_object*, objc_class*) + 116 13 libobjc.A.dylib 0x1ba392e00 objc_destructInstance + 80 14 libobjc.A.dylib 0x1ba39c4fc _objc_rootDealloc + 80 15 UIKitCore 0x1c354f8d8 -[UIResponder dealloc] + 124 16 UIKitCore 0x1c354f5dc -[UIViewController dealloc] + 1084 17 libobjc.A.dylib 0x1ba38e1d4 AutoreleasePoolPage::releaseUntil(objc_object**) + 196 18 libobjc.A.dylib 0x1ba391bdc objc_autoreleasePoolPop + 256 19 UIKitCore 0x1c34ef444 -[_UIAfterCACommitBlock run] + 92 20 UIKitCore 0x1c34ef364 -[_UIAfterCACommitQueue flush] + 168 21 UIKitCore 0x1c34ef278 _runAfterCACommitDeferredBlocks + 496 22 UIKitCore 0x1c338dee4 _cleanUpAfterCAFlushAndRunDeferredBlocks + 108 23 UIKitCore 0x1c384c608 _UIApplicationFlushCATransaction + 72 24 UIKitCore 0x1c399ce00 _UIUpdateSequenceRun + 84 25 UIKitCore 0x1c4000944 schedulerStepScheduledMainSection + 144 26 UIKitCore 0x1c3fffea0 runloopSourceCallback + 92 27 CoreFoundation 0x1c13b4208 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 28 28 CoreFoundation 0x1c13c0864 __CFRunLoopDoSource0 + 176 29 CoreFoundation 0x1c13456c8 __CFRunLoopDoSources0 + 244 30 CoreFoundation 0x1c135b1c4 __CFRunLoopRun + 828 31 CoreFoundation 0x1c13604dc CFRunLoopRunSpecific + 612 32 GraphicsServices 0x1fc5c035c GSEventRunModal + 164 33 UIKitCore 0x1c36ec37c -[UIApplication _run] + 888 34 UIKitCore 0x1c36ebfe0 UIApplicationMain + 340 35 SwiftUI 0x1c4d2e3d8 0x1c4b72000 + 1819608 36 SwiftUI 0x1c4c949b0 0x1c4b72000 + 1190320 37 SwiftUI 0x1c4c7ea54 0x1c4b72000 + 1100372 38 MyApp 0x102f29b48 static MyApp.$main() + 40 39 MyApp 0x102f29bf0 main + 12 40 dyld 0x1e07e8dec start + 2220
问题分析
这是典型的野指针访问错误,崩溃发生在UIKit控制器(UINavigationController、UISplitViewController)的析构阶段,属于自动释放池清理时访问了已释放的内存。结合版本差异,大概率是iOS 16.3+的UIKit与SwiftUI交互bug,或是代码中对UIKit控制器的引用管理不当。
解决建议
- 调整注销时的视图切换逻辑:注销切换根视图时,用
withAnimation包裹操作,或添加极短延迟(比如0.1秒),给UIKit足够时间完成控制器生命周期处理,避免提前释放。 - 清理UIKit控制器的强引用:如果代码中通过桥接方式持有了导航/分栏控制器的强引用,改为
weak var,防止循环引用导致控制器释放异常。 - 排查分栏控制器相关代码:崩溃日志指向
_UISplitViewControllerColumnContents,若使用了分栏布局,检查注销时是否正确重置分栏内容,避免残留无效引用。 - 强制视图重建:在注销相关的视图上添加
.id(UUID()),触发视图完全重建,规避系统优化带来的释放时机问题。 - 升级系统测试:iOS 16.5+修复了大量UIKit/SwiftUI交互bug,测试该版本是否还会崩溃,若问题消失,可提示用户升级,同时代码中做兼容处理。
- 启用Zombies调试:在Xcode中开启Zombie Objects工具(Product > Scheme > Edit Scheme > Diagnostics > Enable Zombie Objects),定位具体被重复释放的对象,精准修复代码问题。
内容的提问来源于stack exchange,提问作者GuoZhiHeHe
相关产品推荐
相关产品推荐

