这个崩溃是一个阻塞问题,我使用以下步骤来重现这个问题:

创建一个Cocoa Touch框架项目 添加一个swift文件和一个类Dog 为设备构建一个框架 在Swift中创建一个单视图应用程序 导入框架到应用程序项目 从ViewController中的框架实例化swift类 在设备上构建并运行应用程序

应用程序在启动时立即崩溃,这是控制台日志:

dyld: Library not loaded: @rpath/FrameworkTest03.framework/FrameworkTest03
  Referenced from: /var/mobile/Applications/FA6BAAC8-1AAD-49B4-8326-F30F66458CB6/FrameworkTest03App.app/FrameworkTest03App
  Reason: image not found

I have tried to build on iOS 7.1 and 8.0 devices, they both have the same crash. However, I can build an app and run on the simulator fine. Also, I am aware that I can change the framework to form Required to Optional in Link Binary With Libraries, but it did not completely resolve the problem, the app crashed when I create an instance of Dog. The behavior is different on the device and simulator, I suspect that we can't distribute a framework for the device using a beta version of Xcode. Can anyone shed light on this?


当前回答

运行时错误:dyld:库未加载:@rpath/<some_path>

这是由动态链接器引起的运行时错误

dyld: Library not loaded: @rpath/<some_path>
Referenced from: <some_path>
Reason: image not found

错误库没有加载@rpath表示动态链接器找不到二进制文件。

Check if the dynamic framework was added to the front target General -> Frameworks, Libraries, and Embedded Content (Embedded Binaries). It is very simple to drag-and-drop a framework to project with Copy items if needed[About] and miss to add the framework as implicit dependency in Frameworks, Libraries, and Embedded Content(or check in Add to targets). In this case during compile time Xcode build it as success but when you run it you get runtime error Check the @rpath setup between consumer(application) and producer(dynamic framework):

动态框架: 构建设置->动态库安装名称 应用程序: 构建设置->运行路径搜索路径 构建阶段->嵌入框架->目标,子路径

框架的Mach-O文件[关于]-动态库和应用程序的框架,库和嵌入式内容[关于]-不嵌入。

动态链接器

Dynamic Library Install Name(LD_DYLIB_INSTALL_NAME) which is used by loadable bundle(Dynamic framework as a derivative) where dyld come into play Dynamic Library Install Name - path to binary file(not .framework). Yes, they have the same name, but MyFramework.framework is a packaged bundle with MyFramework binary file and resources inside. This path to directory can be absolute or relative(e.g. @executable_path, @loader_path, @rpath). Relative path is more preferable because it is changed together with an anchor that is useful when you distribute your bundle as a single directory

绝对路径——Framework1示例

//Framework1 Dynamic Library Install Name
/some_path/Framework1.framework/subfolder1

相对路径允许您以动态的方式定义路径。

@executable_path

@executable_path -相对于加载框架的可执行二进制文件 用例:应用程序内部的动态框架(应用程序二进制路径 是@executable_path)或更复杂的应用程序扩展[关于]的例子,它是包含动态框架的应用程序的一部分。@executable_path用于应用程序目标(应用程序二进制路径为@executable_path)和应用程序扩展目标(应用程序扩展二进制路径为@executable_path)

//Application bundle(`.app` package) absolute path
/some_path/Application.аpp

//Application binary absolute path 
/some_path/Application.аpp/subfolder1

//Framework2 binary absolute path
/some_path/Application.аpp/Frameworks/Framework2.framework/subfolder1

//Framework2 @executable_path == Application binary absolute path <-
/some_path/Application.аpp/subfolder1

//Framework2 Dynamic Library Install Name 
@executable_path/../Frameworks/Framework2.framework/subfolder1

//Framework2 binary resolved absolute path by dyld
/some_path/Application.аpp/subfolder1/../Frameworks/Framework2.framework/subfolder1
/some_path/Application.аpp/Frameworks/Framework2.framework/subfolder1

@loader_path

@loader_path -相对于导致框架被加载的bundle。如果它是一个应用程序,那么它将与@executable_path相同 用例:框架和嵌入式框架- Framework3_1和Framework3_2在里面

//Framework3_1 binary absolute path
/some_path/Application.аpp/Frameworks/Framework3_1.framework/subfolder1

//Framework3_2 binary absolute path
/some_path/Application.аpp/Frameworks/Framework3_1.framework/Frameworks/Framework3_2.framework/subfolder1

//Framework3_1 @executable_path == Application binary absolute path <-
/some_path/Application.аpp/subfolder1

//Framework3_1 @loader_path == Framework3_1 @executable_path <-
/some_path/Application.аpp/subfolder1

//Framework3_2 @executable_path == Application binary absolute path <-
/some_path/Application.аpp/subfolder1

//Framework3_2 @loader_path == Framework3_1 binary absolute path <-
/some_path/Application.аpp/Frameworks/Framework3_1.framework/subfolder1

//Framework3_2 Dynamic Library Install Name 
@loader_path/../Frameworks/Framework3_2.framework/subfolder1

//Framework3_2 binary resolved absolute path by dyld
/some_path/Application.аpp/Frameworks/Framework3_1.framework/subfolder1/../Frameworks/Framework3_2.framework/subfolder1
/some_path/Application.аpp/Frameworks/Framework3_1.framework/Frameworks/Framework3_2.framework/subfolder1

@rpath -跑道路径搜索路径

Framework2例子

以前我们必须设置一个框架来使用dyld。这并不方便,因为相同的框架不能与不同的配置一起使用。由于此设置是在框架目标端进行的,因此不可能为不同的消费者(应用程序)配置相同的框架。

@rpath是一个复合概念,它依赖于外部(应用程序)和嵌套(动态框架)部分:

Application: Runpath Search Paths(LD_RUNPATH_SEARCH_PATHS) - @rpath - defines a list of templates which will be substituted with @rpath. Consumer uses @rpath word to point on this list @executable_path/../Frameworks Review Build Phases -> Embed Frameworks -> Destination, Subpath to be sure where exactly the embed framework is located Dynamic Framework: Dynamic Library Install Name(LD_DYLIB_INSTALL_NAME) - points that @rpath is used together with local bundle path to a binary @rpath/Framework2.framework/subfolder1

//Application Runpath Search Paths
@executable_path/../Frameworks

//Framework2 Dynamic Library Install Name
@rpath/Framework2.framework/subfolder1

//Framework2 binary resolved absolute path by dyld
//Framework2 @rpath is replaced by each element of Application Runpath Search Paths
@executable_path/../Frameworks/Framework2.framework/subfolder1
/some_path/Application.аpp/Frameworks/Framework2.framework/subfolder1

* . ./ -进入当前目录的父目录

对象文件显示工具

//-L print shared libraries used
//Application otool -L
@rpath/Framework2.framework/subfolder1/Framework2

//Framework2 otool -L
@rpath/Framework2.framework/subfolder1/Framework2

//-l print the load commands
//Application otool -l
LC_LOAD_DYLIB
@rpath/Framework2.framework/subfolder1/Framework2

LC_RPATH
@executable_path/../Frameworks

//Framework2 otool -l
LC_ID_DYLIB
@rpath/Framework2.framework/subfolder1/Framework2

Install_name_tool使用-rpath更改动态共享库安装名称

CocoaPods使用use_frameworks![关于]规范动态链接器

(词汇)

(Java ClassLoader)

其他回答

Xcode 11

导航到目标的设置并选择“常规”。 寻找“框架、库和嵌入式内容” 保持“不要嵌入”,并确保你的所有目标(如果你有多个目标)都只设置了自己的框架,而不是其他目标。

我的环境:Cocos2d 2.0, Box2d, Objective C

除了做上面的其他答案,我最后去了General选项卡,并使WatchKit可选。

我不得不(在这里提到的内容之上)将以下一行添加到构建设置选项卡下的Runpath Search Paths: @executable_path /框架

我使用Swift3/Xcode 8.1创建了一个框架,并在Objective-C/Xcode 8.1项目中使用它。为了解决这个问题,我必须在构建选项下启用始终嵌入Swift标准库选项。

看看这张截图:

最近在旧的iPhone(例如iPhone 6)和Xcode(11.3.1)上导入CoreNFC时遇到了这个问题。我就能让它工作了

在项目中,选择目标。 Goto General标签在顶部。 在“框架、库和嵌入式内容”部分,添加框架(对我来说是CoreNFC)。重复其他目标。 点击顶部的Build Phases,展开“Link Binary with Libraries”。 使麻烦的框架成为可选的(从必需的)。

这让我可以在不做任何代码更改的情况下编译旧/新iphone。我希望这能帮助到其他人。