使用CocoaPods将FacebookSDK从7.0.1升级至9.0.1后出现_dispatch_once方法错误的技术求助
我之前也碰到过和你一模一样的坑!把Facebook SDK从7.0.1升级到9.0.1之后,一跑代码就触发了这个_dispatch_once的递归错误,折腾了好半天才搞定,给你分享下我的解决思路和步骤:
这个错误的核心是符号冲突:Facebook SDK 9.x版本内部对dispatch_once相关函数有了新的实现,而你的项目或者其他依赖库中,恰好也存在同名的自定义dispatch_once(可能是老第三方库、自己项目里的兼容代码重定义了这个函数)。链接阶段符号冲突后,最终导致执行时进入无限递归——自定义的_dispatch_once里调用系统dispatch_once,但系统的符号已经被覆盖成自定义的版本,循环往复就触发了错误。
先排查自己项目里的自定义实现
全局搜索项目里的所有文件,看看有没有类似这样的代码:// 自定义宏或者函数重定义 #define dispatch_once(...) // 或者 void _dispatch_once(dispatch_once_t *predicate, dispatch_block_t block) { // 你的自定义逻辑 }如果找到,直接删除或者注释掉这些自定义代码就行,系统原生的
dispatch_once已经足够稳定,而且新版本Facebook SDK完全依赖标准实现。逐个排查第三方库的冲突
先执行pod deintegrate完全卸载所有依赖,然后只安装Facebook SDK 9.0.1,运行项目看是否还报错。如果没问题了,再逐个把之前的pod加回来,每次添加后运行一次,找到那个和Facebook SDK 9.x冲突的库。找到后要么升级该库到兼容版本,要么联系库作者修复符号冲突问题。彻底清理项目缓存
缓存残留经常会导致旧符号没被替换,一定要做这几步:- 关闭Xcode,找到DerivedData目录(Xcode偏好设置->Locations里可以看到路径)直接删除
- 用
Command + Shift + K清理项目构建文件 - 重新执行
pod install,然后打开项目重新构建
检查Build Settings的链接配置
看看项目的Build Settings里,Other Linker Flags有没有-force_load或者-all_load这类全局强制加载的参数。这类参数容易导致符号覆盖冲突,如果有的话,改成只针对特定库加载(比如-force_load $(BUILT_PRODUCTS_DIR)/xxx.framework/xxx),避免全局生效。
Facebook SDK从7.x到9.x做了不少底层架构调整,除了这个符号冲突问题,还可能碰到权限配置、API调用方式的变化,比如登录权限的申请逻辑、Graph API版本的适配,建议同步确认项目的其他适配点。
内容的提问来源于stack exchange,提问作者taimur

