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

问题描述 投票:126回答:3

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

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

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

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

任何帮助或方向将不胜感激。谢谢!

ios xcode frameworks static-libraries
3个回答
177
投票

首先,一些一般定义(特定于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

6
投票

图书馆和框架

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 framework是一个Dynamic framework,放置在应用程序的沙箱中,仅适用于该应用程序。首先为extension创建此类型以共享公共代码和资源。

如何构建和使用在这里阅读:

Swift consumer -> Swift static library

Swift consumer -> Objective-C static library

Objective-C consumer -> Swift static library

Objective-C consumer -> Objective-C static library

链接

The sourceone more。另请阅读更多hereherehereherehere


1
投票

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

© www.soinside.com 2019 - 2024. All rights reserved.