什么时候我们应该在Xcode中使用"嵌入式二进制文件"而不是"链接框架"?

For*_*est 128 xcode frameworks ios embedded-binary

关于这两个选项之间的区别是一个很好的问题,如Link Binary与库VS Embed Frameworks中描述的那样.

似乎我们可以选择使用它们,只是想知道哪种情况我们应该更好地使用嵌入式二进制文件,或者不是链接框架?

解决这个问题的任何可靠实例都更清晰 谢谢

par*_*par 220

您链接的问题引用了"Link Binary With Libraries"功能,这与嵌入式二进制文件有些不同.

"链接二进制文件库"意味着您对链接的期望:无论二进制文件是静态库,动态库还是框架,它都会在编译后的链接时链接到您的目标代码.

当您考虑与静态库的链接时,发生的事情非常清楚:链接器将库中的代码(例如)复制libFoo.a到输出二进制文件中.您的输出文件大小增加,但不需要在运行时解析任何外部依赖项.在构建之后,程序需要运行的所有内容(相对于静态库)都存在.

使用动态库(.dylib或系统提供的框架),期望在运行程序时,链接的库将出现在系统的动态库加载器路径中的某个位置.这样您就不会有将所有第三方外部库复制到二进制文件中的开销,并且连接到该库的计算机上的所有不同程序都能够找到它,这样可以节省最少的磁盘空间,而且可能的内存空间,具体取决于系统缓存库的方式和位置.

框架很像动态库,但可以在其目录结构中包含资源(图像,音频,其他框架等).在这种情况下,一个简单的静态库或名为.dylib文件将不会削减它,所以你可能需要链接到一个框架,只是这样可以找到它所需要的正常运行.

当您链接到第三方框架(比如您从github下载并自行构建的内容)时,它可能不会出现在您打算运行的系统上.在这种情况下,您不仅可以链接到框架,还可以使用"复制框架"阶段将其嵌入到应用程序包中.当程序运行时,除了系统加载器路径之外,运行时链接程序(也称为解析程序)将查看包中的内容,找到嵌入式框架并链接它,以便您的应用程序将拥有运行所需的代码.

最后,正确的"嵌入式二进制文件"是一个可执行文件,您可以通过复制文件阶段嵌入应用程序包中,并且您可以自己执行,也许可以通过调用popen()或类似方式执行.嵌入式二进制文件可能由您的程序调用,但它不与它链接.它是一个完全外部的实体(就像/bin目录中的程序一样).

实际上,对于系统提供的库和框架,您将链接它们,这就是您需要做的所有事情.

如果您需要链接您构建的不需要任何嵌入资源的库(即不需要框架存在),那么您只需链接到静态库即可.如果您发现程序中有多个模块想要使用相同的库代码,那么将其转换为框架或动态库并进行链接可以节省空间并且可能很方便(特别是如果考虑内存使用情况).

最后,框架不仅可以包括资源,还可以包含头文件和/或许可证文件.使用框架来传达这些文件实际上是一种方便的分发机制,因此通常您可能希望合并框架,以便这些东西可以与您的二进制一起标记(即许可证要求可能使其成为必需的).

---编辑---

Adam Johns发表以下问题作为评论:

这是一个很好的答案.然而,有些东西我仍然有些困惑.自己执行二进制文件意味着什么?你的意思是简单地使用嵌入式框架的代码吗?我知道你提到了popen(),但你说我的应用程序正在调用popen()?我真的不知道这意味着什么.

我说嵌入式二进制文件只是包中的另一个资源文件,如音频文件或图像,尽管该文件是可执行的命令行工具.该popen()函数(man popen从您的终端读取更多信息)允许您从另一个正在运行的程序执行任意程序.该system()功能是另一种方式.还有其他的,我将在这里给出一个历史的例子,可以更清楚地理解嵌入式二进制文件的使用:

您可能已经注意到,当您在Mac OS X上启动应用程序时,它会以当前用户的用户ID启动.在大多数常见安装下,这是默认的桌面admin用户,具有用户ID 501.

在基于Unix的操作系统上,只有root用户(用户标识0)才能完全访问整个文件系统.有时,桌面用户启动的安装程序需要在特权目录(例如驱动程序)中安装文件.在这种情况下,应用程序需要将其权限升级到root用户,以便它可以在这些受限制的目录中写入.

为了通过OS X 10.7在操作系统中实现这一点,Apple在其Authorization Services API中提供AuthorizationExecuteWithPrivileges()函数(现在已弃用,但仍然是一个有用的示例).

AuthorizationExecuteWithPrivileges()将执行命令行工具的路径作为参数root.命令行工具是您编写的用于运行安装逻辑的可执行shell脚本或编译二进制文件.此工具安装在应用程序包中,就像任何其他资源文件一样.

当被调用时,操作系统会建立一个授权对话框,询问用户的密码(您之前已经看过了!),输入后将root代表您的应用程序执行该程序.这个过程类似于只是popen()自己执行一个程序,虽然popen()单独没有给你特权升级的好处.

  • 你怎么知道这些事情? (51认同)
  • @IanWarburton我已经为Apple操作系统编程了20多年,并在这里和那里获得了一些花絮.:) (45认同)

Bri*_*ure 29

简而言之,

  • 系统库,链接它们;
  • 第三方图书馆,嵌入它们.

为什么?

  • 如果您尝试嵌入系统库,则无法在弹出列表中找到它们;
  • 如果你链接第三方库,你可能会崩溃.


yoA*_*ex5 11

Xcode v11 之前的版本。嵌入式二进制文件与链接框架和库

历史

Embedded Binaries vs Linked Frameworks and Libraries -> Frameworks, Libraries, and Embedded Content
Run Code Online (Sandbox Code Playgroud)

[Xcode v11. Frameworks, Libraries, and Embedded Content]General标签中的Xcode v11 部分替换了它

embedded binaries并且Linked FrameworksDependency管理的一部分[关于]

[Xcode v11]

链接二进制

General -> Linked Frameworks and Libraries是 的一面镜子Build Phases -> Link Binary With Libraries

静态库和框架

如果添加Static Library or Static Framework到本节将出现在Frameworks [关于]Project Navigator -> <workspace/project> -> Frameworks),而且将被添加到您的项目为它的参考。然后它将被Static Linker. Static Linker在编译时会将库中的所有代码包含/复制到可执行对象文件中。Static linker配对工作Build Settings -> <Library/Framework> Search Paths

Static Library

Static Framework

  • Build Settings -> Framework Search Paths. 如果你不添加 astatic framework到这个部分,你会得到一个编译错误[No such module]

嵌入二进制

静态库和静态框架

嵌入对 a 没有任何意义Static LibraryStatic Framework因为它们的符号被编译成可执行二进制文件。Xcode 不会让您static library在 Embed 部分下放置一个。

动态框架

General -> Embedded Binaries是 的一面镜子Build Phases -> Embed Frameworks

嵌入实际上是框架的副本添加到您的应用程序包中(不是将框架和应用程序的代码合并到单个可执行二进制文件中)

默认情况下,bundle 的文件夹是,Frameworks但您可以使用Destinationfield更改它。此外,您可以指定一个Subpath.

Dynamic linker :dyld加载或运行时将尝试使用[About]查找嵌入式框架,如果未找到,则会发生错误[dyld: Library not loaded]@rpath

结果:

  • Static Library —— Link
  • Static Framework —— Link
  • Dynamic Framework —— Embed

[静态与动态链接器]
[使用链接和嵌入时]
[词汇]


归档时间:

查看次数:

27046 次

最近记录:

5 年,10 月 前