iOS动态库添加失败,报错:dyld: Library not loaded: @rpath/xxx.framework

335 阅读4分钟

错误信息

在接入第三方库的时候,突然报错 dyld: Library not loaded: @rpath/xxx.framework,并且在对应的App包中无法找到集成的SDK。

dyld[8816]: Library not loaded: '@rpath/xxxxx.framework/xxxxxx' Referenced from: '/private/var/containers/Bundle/Application/A91EA5EB-FCCC-40C3-A30E-7A055EE2D53B/XXX.app/xxxx' Reason: tried: '/System/Library/Frameworks/XXXX.framework/xxxxx' (no such file)

在 App 文件中显示包内容,发现在Framework路径下,是存在引入的第三方库。所以证明拷贝是成功的。

错误解决

在Xcode配置中,检查有没有设置rpath,搜索 search找到RunpathSearchPaths。如果没有需要手动添加 @executable_path/Frameworks,如下图所示:

image.png

动态库和静态库 区别

在 iOS 开发中,动态库(Dynamic Library)和静态库(Static Library)是两种常见的库文件类型。它们的主要区别在于链接方式、内存管理和更新机制等方面。

1. 链接时机

  • 静态库:在编译阶段,静态库会被链接到最终的可执行文件中。静态库的代码在编译时就被嵌入到应用中,应用运行时不需要再加载静态库。
  • 动态库:动态库在运行时由操作系统加载到内存中,应用程序启动时不会将动态库的代码嵌入到可执行文件中,而是通过动态链接的方式在应用启动时加载。也就是说,动态库的链接发生在程序运行时。

2. 文件大小

  • 静态库:静态库的代码被直接嵌入到应用程序的可执行文件中,因此应用的最终文件较大。
  • 动态库:动态库的代码在不同的程序间共享,多个应用可以共用同一个动态库文件,因此每个应用的文件大小较小。

3. 更新与版本控制

  • 静态库:如果静态库需要更新,必须重新编译整个应用程序,生成新的可执行文件。这意味着每次更新静态库时都需要重新发布整个应用。
  • 动态库:动态库的更新不需要重新编译应用,只需要替换掉动态库的文件,应用程序在运行时自动加载新的版本,提供了更灵活的更新机制。

4. 内存管理

  • 静态库:每个使用静态库的应用程序都会独立拷贝一份静态库的代码到内存中,因此多个应用程序同时运行时,每个应用都会占用自己的静态库副本。
  • 动态库:多个应用程序可以共享同一份动态库的内存,这样可以节省内存空间,减少重复加载的开销。

5. 加载方式

  • 静态库:在编译时就决定了库的加载方式。它在编译时完全链接到应用程序中,不依赖于运行时的动态加载。
  • 动态库:在运行时动态加载,操作系统负责加载和卸载动态库。

6. 应用场景

  • 静态库:适用于库代码不需要频繁更新、需要最大化性能且不依赖于运行时共享资源的情况。
  • 动态库:适用于库代码需要频繁更新或多个应用程序之间共享相同的代码的情况。

总结

特性静态库 (Static Library)动态库 (Dynamic Library)
链接时机编译时静态链接运行时动态链接
文件大小可执行文件较大应用文件较小,因为共享动态库代码
更新机制更新库时需要重新编译应用程序更新库时无需重新编译应用
内存管理每个应用独立加载库文件多个应用共享相同的库文件
加载方式在编译时完全链接在运行时由操作系统动态加载
应用场景适用于不频繁更新的库适用于多个应用共享相同库、频繁更新的库

选择使用动态库还是静态库,取决于具体的需求和场景。在 iOS 中,动态库通常表现为 .dylib.framework 文件,而静态库表现为 .a 文件。