当前位置: 首页 > 知识库问答 >
问题:

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

楚岳
2023-03-14

关于这两个选项之间的区别,有一个很好的问题,如链接二进制与库VS嵌入式框架中所述。

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

共有1个答案

公羊英达
2023-03-14

您链接的问题引用了“用库链接二进制”功能,这与嵌入式二进制有些不同。

“link Binary With Libraries”指的是您对链接的期望:无论二进制文件是静态库、动态库还是框架,它都将在编译后的链接时间链接到您的目标代码。

当您想到与静态库的链接时,发生的情况非常清楚:链接器将库中的代码(例如libfoo.a)复制到您的输出二进制文件中。输出文件的大小会增大,但不需要在运行时解析任何外部依赖关系。您的程序需要运行的所有东西(相对于静态库)都在它构建之后出现。

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

框架很像一个动态库,但可以在其目录结构中包含资源(图像、音频、其他框架等)。在这种情况下,一个简单的静态库或.dylib文件不会剪切它,所以您可能必须链接到一个框架,这样它才能找到正常运行所需的内容。

当您链接到第三方框架时(比如说您从github下载并自己构建的东西),它可能并不存在于您打算运行的系统上。在这种情况下,您不仅要链接到框架,还要使用“复制框架”阶段将其嵌入到应用程序包中。当您的程序运行时,运行时链接器(也称为解析器)将在系统加载器路径之外查看您的包内,找到嵌入式框架,并将其链接起来,这样您的应用程序将拥有运行所需的代码。

最后,所谓的“嵌入式二进制”是通过复制文件阶段嵌入到应用程序包中的一个可执行文件,您可以自己执行,可能是调用popen()或类似的文件。您的程序可能会调用嵌入式二进制文件,但它不与之链接。它是一个完全外部的实体(就像/bin目录中的程序)。

在实践中,对于系统提供的库和框架,您将根据它们进行链接,这就是您需要做的全部工作。

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

最后,框架不仅可以包括资源,还可以包括头文件和/或许可证文件。使用框架来传递这些文件实际上是一种方便的分发机制,所以通常您可能想要合并一个框架,以便这些东西可以与您的二进制文件一起进行标记(例如,许可证要求可能使这是强制性的)。

---编辑---

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

在基于UNIX的操作系统上,只有root用户(用户id0)对整个文件系统具有完全访问权限。有时,桌面用户启动的安装程序需要在特权目录中安装文件(例如驱动程序)。在这种情况下,应用程序需要将其特权提升到root用户,以便能够在这些受限目录中进行写入。

为了在通过OS X 10.7的操作系统中实现这一点,Apple在其授权服务API中提供了AuthorizationExecuteWithPrivileges()函数(现在不推荐使用,但仍然是一个有用的示例)。

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

当被调用时,OS会显示一个授权对话框,询问用户的密码(您以前已经看到过了!)并且在输入时将代表应用程序以root的身份执行该程序。这个过程类似于只使用popen()自己执行一个程序,尽管单独使用popen()并不能使您获得特权提升的好处。

 类似资料:
  • 有一个关于这两个选项之间的差异的好问题,如链接二进制库VS嵌入框架中所述。 似乎我们可以同时使用它们,只是想知道在哪种情况下我们应该更好地使用嵌入式二进制文件,还是使用链接框架? 有没有更清晰的实例来说明这一点?谢谢

  • 问题内容: 我是一名C ++程序员,偶尔使用MySQL处理数据库,但是我的SQL知识非常有限。但是,我当然愿意改变这一点。 目前,我正尝试仅通过SQL查询对数据库中的数据进行分析(!)。但是我将放弃,而是将数据导入C 并使用C 代码进行分析。 我已经与同事讨论了这一点,他们也促使我使用C ++,他说SQL并不是用于复杂的分析,而是主要用于导入(从现有表中)和导出(到新表中)数据,还有更多内容。例如

  • 问题内容: 我正在使用’multiprocess.Pool.imap_unordered’如下 我需要打电话或之后的for循环? 问题答案: 不,您没有,但是如果您不再使用游泳池,那可能是个好主意。 Tim Peters在此SO帖子中致电或致电的理由很明确: 至于Pool.close(),您应该在永远不会将更多工作提交给Pool实例的情况下(且仅在)进行调用。因此,通常在主程序的可并行化部分完成时

  • 问题内容: 面试官问我: 什么是Observer,什么Observable时候应该使用它们? 我并不了解这些术语,因此当我回到家并开始使用GoogleObserver和Google搜索时Observable,从不同的资源中发现了一些要点: 1)Observable是一个类,Observer是一个接口。 2)Observable该类维护一个Observers的列表。 3)当一个Observable对

  • 我有两个文件,第一个是todoHelper。js 它有 导入{addTodo} 但我也看到人们在做默认导出,而不仅仅是导出。有什么区别?

  • 问题内容: 我在ORM上还很新。我刚刚开始阅读有关使用Hibernate的Java Persistence API的书籍和文档。 我只是想知道,关闭EntityManagerFactory与jdbc数据库连接关闭类似吗? 我们是否应该在每次持久/更新/删除后关闭它?如果我们不关闭它,数据库连接会保持打开状态吗? 问题答案: 我只是想知道,关闭与jdbc数据库连接关闭类似吗? 这并非完全正确,但关闭