图书馆?静态的?动态?还是框架?项目在另一个项目内

时间:2013-03-11 04:07:49

标签: ios xcode frameworks static-libraries

我有一个现有的iOS应用程序,并希望添加一大块代码,我一直在开发另一个项目,以方便测试。新块主要处理将图像保存到各种共享服务等等。因为共享代码需要大量测试和未来更新,我想知道将代码块合并到现有应用程序的最佳方法是什么。

我不知道它应该是静态库,动态库还是框架,老实说,我不确定区别是什么,或者我应该怎么做才能在Xcode中设置它

我所知道的是,我需要/想要为共享代码单独测试和更新应用程序,并让主应用程序使用它。

如果你还不能说,我不是一个git wiz。我只是一个简单的单人开发人员。

任何帮助或指示都将不胜感激。谢谢!

4 个答案:

答案 0 :(得分:173)

首先,一些一般定义(特定于iOS):

静态库 - 在编译时链接的代码单元,不会更改。

但是,iOS静态库允许包含图像/资源(仅限代码)。您可以使用媒体包来解决这一挑战。

在维基百科 here上可以找到更好,更正式的定义。

动态库 - 在运行时链接的可能更改的代码和/或资产的单位。

但是,只允许Apple为iOS创建动态库。您不能创建这些,因为这会让您的应用被拒绝。 (参见this其他SO帖子进行确认和推理。

软件框架 - 完成任务的一组编译代码......因此,您实际上可以拥有静态框架动态框架,通常只是上面的编译版本。

有关详细信息,请参阅Wiki on Software Framework

因此在iOS上,您唯一的选择基本上是使用静态库或静态框架(主要区别在于静态框架最常被分发为编译的.a文件,而静态库可能只是包含在子项目中 - 您可以看到所有代码 - 首先编译的代码和由此产生的.a文件用作项目的依赖项。)

现在我们对这些术语很清楚(呃),设置一个静态库并支持iOS的媒体包并不是很困难,并且有很多教程如何做到这一点。我个人会推荐这个:

https://github.com/jverkoey/iOS-Framework

这是一个非常简单的指南,并没有处理“假静态库”的缺点...查看更多信息......

一旦你创建了静态库,它就像在Git中包含它作为子模块一样简单,以便在不同的项目中使用。

祝你好运。

修改

关于项目中的子项目,据我所知,要使其正常工作/编译,你基本上必须建立一个编译链,其中首先编译子项目,这将创建一个静态框架.a文件,用作项目的依赖项。

这是另一篇有用的教程:

http://www.cocoanetics.com/2011/12/sub-projects-in-xcode/

编辑2

从iOS 8开始,Apple现在允许开发人员创建动态框架! (注意:您的应用必须具有iOS 8的最低目标才能包含动态框架...不允许后端移植。)

这已添加为新项目模板。在Xcode 6.1中,可以在以下位置找到:

New Project -> iOS -> Framework & Library -> Cocoa Touch Framework

答案 1 :(得分:3)

库和框架

Martin Fowler on InversionOfControl

  

从本质上讲,库是可以调用的一组函数,这些天通常组织成类。每个调用都会完成一些工作,并将控制权返回给客户端。

     

框架体现了一些抽象设计,并内置了更多行为。要使用它,您需要通过子类化或插入自己的类将行为插入框架中的不同位置。然后,框架的代码在这些位置调用您的代码。程序的主控件被反转,从您移至框架。 (控制反转)

Mach-O文件格式(.o)

在iOS世界中,每个源文件都转换为目标文件-Mach-O(马赫对象)文件格式[About],该文件格式将打包为最终文件(例如应用程序,框架,库)

iOS上的库和框架

Library是为一个或多个体系结构编译的Mach-O目标文件的集合[check static or dynamic]

Static library-.a(又名静态档案库,静态链接共享库[doc])-在静态链接器期间将其添加到应用程序中strong>编译时间将合并库中的目标文件,并将它们与应用程序目标文件一起打包到一个可执行文件中。缺点是输出文件很大

从Xcode 9.0开始,支持静态Swift库。

Dynamic library-.dylib(又名动态共享库,共享库,动态链接库[doc])与应用程序的可执行文件动态链接加载或运行时,但未复制到其中。在实践中,应用程序的软件包将包含带有.dylib文件的Frameworks文件夹。所有iOS和macOS 系统库均为dynamic。缺点是启动时间很慢,因为所有动态库都应复制并链接。

Text-based stub library-.tbd [About],它是dynamic library的文本存根,位于目标设备上。因此,您不应将动态库打包到包中。它具有尺寸效果。

Bundle是一种文件夹,可以包含文件,文件夹和子文件夹。通常它由object files和资源(例如图像,笔尖...)组成

Framework-.frameworkbundle,其中包含static or dynamic[static vs dynamic framework],头文件和资源。

Static framework包含一个static library及其资源。

Dynamic framework包含dynamic library及其资源。除此之外,动态框架可以在一个捆绑包中包含同一动态库的不同版本

Embedded frameworkdynamic framework,位于应用的沙箱中。首先为extension创建此类型,以共享公共代码和资源。当“部署目标”为iOS 8+时可用。

Umbrella framework [Aggregate target]是一个包含其他框架的框架。 iOS上官方不支持它,这就是为什么不推荐供开发人员创建它的原因[Official doc]。实际上,它是一组子框架(或嵌套框架)。当您创建具有依赖项的框架时,消费者(例如应用程序)负责将这种依赖项与您的框架一起添加到项目中。作为开发人员,您自然会尝试找到一种方法,将这种责任从消费者转移到您的责任。结果,您认为Umbrella framework是可以解决的,但通常会导致版本管理以及创建和支持它的复杂性方面的严重问题。

Fake Framework-是在static library下进行特定操作以创建扩展名为.framework的捆绑软件的结果,该捆绑软件将表现为dynamic framework。由于Xcode由于没有框架模板而不支持创建框架时,才使用此技术。 fake framework的实现之一。苹果使用Xcode 6添加了iOS框架支持。

Modular Framework [About]-@import是一个框架,其中包含一个.modulemap文件。模块可以包含子模块。主要优点是可以节省Modular Framework的构建时间。

Universal Library or Framework(又名胖子)[lipo] [Aggregate target]包含多种体系结构。例如,您的发行版本应支持某个拱形,您可以通过Build Active Architecture Only [ONLY_ACTIVE_ARCH]

进行调节

Dependency [About]您可以将第三方代码用作目标的一部分。它使您可以重用来自许多来源的代码,例如-另一个项目,同一工作空间中的项目,另一个目标,库,框架等。

如何构建和使用静态库:

如何构建和使用动态框架[change to static]

[Xcode Build System]
[Xcode components]

答案 2 :(得分:2)

库和框架

Martin Fowler on InversionOfControl

library本质上是可以调用的一组函数,这些天通常组织成类。每个调用都会完成一些工作,并将控制权返回给客户端。

framework体现了一些抽象设计,并内置了更多行为。要使用它,您需要通过子类化或插入自己的类将行为插入框架中的各个位置。然后,框架的代码将在这些位置调用您的代码。

iOS上的库和框架

library是为一个或多个体系结构编译的资源和代码本身的集合。它由*.o个文件(Mach-O对象文件)组成。

对于static libraries (*.a),在static linker期间compilation time将应用程序使用的代码复制到生成的可执行文件中。

从Xcode 9.0开始,现在支持静态Swift库

✓优点:

  • 保证静态库存在于应用程序中并具有正确的版本。
  • 无需使应用程序保持库更新的最新状态。
  • 更好地执行库调用。

✕缺点:

  • 夸大的应用程序大小。
  • 启动时间因应用可执行文件过大而降低。
  • 即使使用单个功能,也必须复制整个库。

Dynamic libraries (*.dylib)static libraries的不同之处在于,它们与应用程序的可执行文件在loadruntime上动态链接,但没有被复制到其中。结果,可执行文件更小,并且由于仅在需要时才加载代码,因此启动时间通常更快。

所有iOS和macOS系统库都是动态的。因此,我们的应用程序将受益于Apple对标准库框架所做的未来改进,而无需创建和发布新版本。

✓优点:

  • 无需重新编译应用程序即可受益于库的改进。对于系统库尤其有用。
  • 占用更少的磁盘空间,因为它在应用程序之间共享。
  • 更快的启动时间,因为它是在运行时按需加载的。
  • 分段加载:如果使用单个函数,则无需加载整个库。

✕缺点:

  • 如果库中发生任何更改,则有可能破坏程序。
  • 对库函数的调用较慢,因为它位于应用程序可执行文件之外。

bundle是其中包含子目录的文件目录。在iOS上,bundles用于将相关文件方便地一起打包到一个包中,例如图像,笔尖或编译后的代码。系统将其视为一个文件,您可以在不知道其内部结构的情况下访问捆绑软件资源。

library可能还具有其他资源:标头,本地化文件,图像,文档和使用示例。我们可以将所有这些捆绑在一起,成为一个bundle –其名称为framework

framework (*.framework)bundle的一种特殊类型。对其结构进行很小的更改,它甚至可以包含其他框架。这种聚合称为umbrella framework

Static frameworks包含与资源打包在一起的static library

Dynamic frameworks包含dynamic library及其资源。除此之外,dynamic frameworks可以方便地在同一框架中包含同一dynamic library的不同版本!

如果您的部署目标是iOS8 +,那么您也可以创建embedded framework

Embedded frameworkDynamic framework,放置在应用程序的沙箱中,仅对该应用程序可用。首先为extension创建此类型,以共享公共代码和资源。

The sourceone more。另请阅读更多hereherehereherehere

答案 3 :(得分:1)

你也可以为CocoaPods(http://guides.cocoapods.org/making/private-cocoapods.html#1.-create-a-private-spec-repo)创建.podspec文件,并像任何其他pod一样使用它,唯一的区别是它是你的私人pod并且对外界不可见(我不确定会是什么如果你的pod应该创建CoreData模型会发生,但事实并非如此,正如我所理解的那样。