将Unity库嵌入Xcode项目后出现运行时崩溃问题
解决iOS原生项目嵌入UnityFramework时的libdispatch递归锁崩溃问题
环境信息
- Unity版本:6000.0.31f1
- Xcode版本:16.1(16B40)
- 目标平台:iOS Simulator(Unity以Universal模式构建)
崩溃详情
构建运行嵌入UnityFramework的原生Swift项目时触发运行时崩溃,错误提示:BUG IN CLIENT OF LIBDISPATCH: trying to lock recursively
崩溃调用栈:
libdispatch.dylib`_dispatch_once_wait.cold.1: 0x10380add8 <+0>: stp x20, x21, [sp, #-0x10]! 0x10380addc <+4>: adrp x20, 6 0x10380ade0 <+8>: add x20, x20, #0xaf0 ; "BUG IN CLIENT OF LIBDISPATCH: trying to lock recursively" 0x10380ade4 <+12>: adrp x21, 39 0x10380ade8 <+16>: add x21, x21, #0x1e8 ; gCRAnnotations 0x10380adec <+20>: str x20, [x21, #0x8] 0x10380adf0 <+24>: ldp x20, x21, [sp], #0x10 -> 0x10380adf4 <+28>: brk #0x1
复现步骤
- 在Xcode中创建带Storyboard的Swift示例iOS项目;
- 创建名为Bridge的工作区,添加NativeIOSApp和UnityIphone项目;
- 为UnityFramework设置Target Membership;
- 在NativeIOSApp的Build Settings中嵌入UnityFramework;
- 构建运行后触发崩溃。
修复方案
1. 调整UnityFramework初始化时机
Unity的初始化逻辑不能在持有libdispatch锁的代码块(比如dispatch_once、主线程初始化闭包)中执行,建议将初始化放在后台线程:
DispatchQueue.global(qos: .background).async { guard let unityFramework = UnityFramework.sharedInstance() else { return } unityFramework.setDataBundleId("your.unity.bundle.id") unityFramework.runEmbedded(withArgc: CommandLine.argc, argv: CommandLine.unsafeArgv, appLaunchOpts: nil) }
2. 修改Unity构建配置
- 打开Unity
Player Settings > iOS > Other Settings,将Scripting Backend切换为IL2CPP(Mono后端在Xcode 16模拟器环境下易出现线程锁兼容问题); - 开启Strip Engine Code,剔除冗余的线程初始化代码;
- 关闭Autoconnect Profiler,避免调试工具的线程冲突。
3. 修正Xcode项目Target配置
- 确保UnityFramework的
Target Membership仅勾选UnityFramework目标,不要勾选原生项目Target; - 在原生项目的
Build Phases > Embed Frameworks中,将UnityFramework的Embed设置为Embed & Sign,并勾选Code Sign On Copy; - 统一原生项目和Unity项目的Deployment Target(建议设为iOS 15.0及以上)。
4. 规避Xcode 16模拟器的libdispatch限制
- 在Xcode的
Edit Scheme > Run > Arguments > Arguments Passed On Launch中添加参数:OS_ACTIVITY_MODE=disable,关闭部分系统日志检测; - 切换到iOS真机测试,部分模拟器特有的锁问题在真机环境下不会触发。
内容的提问来源于stack exchange,提问作者Selvaraj Balakrishnan
相关产品推荐
相关产品推荐

