iOS Release 包 [symbol not found] 排查:Xcode 符号裁剪误伤 FFI
背景
Flutter 项目中集成了 tencent_rtc_sdk 实现语音/视频通话功能。Debug 真机调试一切正常,但打出 Release 包(TestFlight / 蒲公英 IPA)安装到真机后,发起通话直接崩溃,日志里出现:
1 | symbol not found: Dart_InitApiDL |
本文记录这个问题的根因和修复方案。
原因
tencent_rtc_sdk 通过 Flutter FFI(Foreign Function Interface)调用底层 C/C++ 接口,核心机制是:
1 | // Dart 端通过 DynamicLibrary 在运行时查找 native 符号 |
它依赖系统 dlsym(RTLD_DEFAULT, ...) 在运行时动态解析 C 符号。
在 Debug 构建中,Xcode 不会进行符号裁剪,所有符号完整保留,所以一切正常。
但 Release 构建时,Xcode 的链接优化会:
- 符号裁剪(Strip) — 移除未被直接引用的符号,减小包体积
- 死代码消除(Dead Code Stripping) — 移除未显式调用的代码段
由于 FFI 调用的符号在编译期「看起来」没有被引用(它们是通过字符串在运行时查找的),链接器误将它们判定为无用符号并删除,导致 dlsym 解析失败,引发 symbol not found 崩溃。
1 | ┌────────────────────────────────────────────────────────┐ |
解决方案
在 Xcode 的 Build Settings 中调整两项配置,让 Release 构建保留 FFI 所需的符号。
步骤一:开启 Deployment Postprocessing
在项目的 Build Settings 中搜索 Deployment Postprocessing,将 Release 的值设为 Yes。

这个选项控制是否在构建完成后进行符号处理。设为 Yes 后,后续的 Strip Style 设置才会生效。
步骤二:修改 Strip Style
在 Build Settings 中搜索 Strip Style,将 Release 的值设为 Non-Global Symbols。

| Strip Style 选项 | 效果 |
|---|---|
| All Symbols | 移除全部符号,FFI 必然失败 |
| Non-Global Symbols(推荐) | 只移除本地符号,保留全局符号(dlsym 需要的都在全局表中) |
| Debugging Symbols | 仅移除调试符号 |
备选方案:链接器 Flag(已兜底)
项目中也配置了 -Wl,-export_dynamic 链接器 flag,作为兜底策略。在 ios/Flutter/Release.xcconfig 中:
1 | OTHER_LDFLAGS = $(inherited) -Wl,-export_dynamic |
-export_dynamic 告诉链接器将所有全局符号标记为可导出,确保 dlsym 能找到它们。
推荐两者都配上:Strip Style = Non-Global Symbols 控制 Xcode 的符号处理行为,-export_dynamic 控制链接器的导出策略,双重保障。
配置汇总
| 配置项 | 位置 | Release 值 | 作用 |
|---|---|---|---|
| Deployment Postprocessing | Build Settings | Yes | 启用符号处理 |
| Strip Style | Build Settings | Non-Global Symbols | 保留全局符号 |
| OTHER_LDFLAGS | Release.xcconfig | -Wl,-export_dynamic |
强制导出符号 |
配置完成后,重新 Archive → 导出 IPA → 真机安装测试,通话功能恢复正常。
验证
- 用 Release 配置打包(Archive → Distribute)
- 安装到真机(不要用 Debug 包替代验证)
- 进入通话流程,发起呼叫
- 如果仍有问题,在 Xcode Console 中过滤
dlsym、DynamicLibrary、symbol not found关键词排查
延展:哪些场景会遇到这个问题?
不只是 tencent_rtc_sdk,任何通过 Dart FFI 调用 C 库的依赖都可能命中这个坑,比如:
sqlite3/sqlite3_flutter_libsffi+ 自定义 .a / .framework- 其他使用
DynamicLibrary.process()的三方 SDK
如果你的 Release 包出现莫名其妙的 symbol not found,第一条排查思路就是:Xcode 是不是把你的 FFI 符号给 Strip 掉了。







![iOS Release 包 [symbol not found] 排查:Xcode 符号裁剪误伤 FFI](/images/cover-ios-ffi-fix.png)
