多个框架和公共库

使用iOS 8, Xcode 6

假设我有两个dynamic框架, frameworkAframeworkB ,它们都依赖于libC 。 另外,我有一个使用frameworkAframeworkB的应用程序。 我最初的想法是使frameworkAframeworkB伞架和libC成为一个子框架。 然而,苹果公司反对伞架构,并且这篇文章描述了伞架由于潜在的链接器冲突问题而成为坏主意的原因。

我的第二个select是使用cocoapods(对于这个还是新的,所以对于细节有些模糊)使用libC作为一个pod,然后将其编译到frameworkAframeworkB 。 但是,我想到这两个框架仍然有它自己的libC副本。 由于该应用程序使用这两个框架,这是否也会导致链接器冲突问题? 有没有更好的方法来解决这个问题?

更新 @Rob我工作的项目确实需要复杂的依赖关系pipe理,但我在问题中保持了问题域的简单性,试图更好地理解如何使用cocoapods可以帮助解决伞架的链接器冲突问题。 我和一群编写库的开发人员合作,可以依靠彼此的基本库来提供版本化的公共API。 我们被要求打包和交付尽可能less的图书馆到一个不同的组织,这是与我们的图书馆build立一个应用程序,他们的一个关键要求是,我们提供了一个dynamic的框架。

解决大多数问题的最好方法是把所有代码放在一个项目中并编译。 当你遇到使问题出现的专门问题时,你应该看看其他解决scheme,比如静态库,最后是框架。

静态库可以是有意义的,如果你有一个代码库,有片断,需要不同的构build要求。 如果所有的部分都具有相同的构build设置,那么只需从“公共”目录“添加文件”到您的项目中,然后构build您的项目。 如果您的构build时间非常长,静态库可能会很有吸引力,而且有些构件永远不会改变,您希望能够“清理”而不重build这些构件。 但是等到你开始有这个问题,然后再去做复杂的多包项目。

如果您销售封闭源码库,那么框架非常有吸引力。 出于您注意的原因,您应该强烈避免添加第三方依赖项。 如果你必须的话,最好的方法是帮助你的客户把所有的东西打包成框架,并把它们连接在一起。 但是这增加了很多烦恼; 所以确保你真的需要这个第三方的一块。

如果你有一个非常大的可重用代码,它有自己的生命周期与主要产品分开,你也可以考虑框架。 但是,再次保持简单。 避免第三方内容,如果你必须有第三方的东西,然后让消费者在最后链接它。

(这不是一个新的解决scheme,顺便说一句,当你使用curl时,如果你想使用SSL,你还需要下载和构buildOpenSSL并将它们连接在一起,Curl并不随OpenSSL内置。

但在绝大多数情况下,这都是矫枉过正的。 不要跳到框架。 不要跳到图书馆。 只需把所有的代码放在项目中并编译即可。 你的问题的90%将会蒸发。 尤其是iOS项目通常并不那么重要。 什么问题是一个框架解决?

如果你的组织在很多产品中使用了很多代码,那么我听说很多团队使用内部的CocoaPods来pipe理这些代码。 但这只是为了简化代码的检查。 它仍然全部进入一个项目,并将它们一起编译成一个二进制文件。 没有框架需要。 dynamic框架对于某些以前非常痛苦的问题是一个很好的特性。 但是,在大多数情况下,他们只是在寻找一个问题的复杂性。

(如果您遇到这些特殊问题之一,请编辑您的问题,我很乐意进一步讨论您将如何处理这个问题。)


编辑:(你属于那个“专业问题”,所以让我们来谈谈这个问题,我也在多个团队的Mac和iOS开发环境中做了很多年,而且我们尝试了几乎所有不同的解决scheme,包括框架。他们只是在iOS上新的。)

在你描述的一个组织中,我强烈build议把每个依赖包作为自己的框架(AFNetworking,JSONKit等等)和你的每个部分作为一个框架,然后让应用程序把它们连接在一起。 通过这种方式,与其他dynamic库(libcurl,openssl等)相同,它们需要应用程序开发者将所有内容链接在一起。

在任何情况下,dynamic框架都不应该包含其他可能被要求的框架(即框架不应该包装“第三方”的东西)。 这将爆炸。 你不能让它不爆炸。 你要么膨胀,build立冲突,或运行时冲突。 这就像合并冲突。 开发人员必须做出select。 应用程序级链接正在做出该select。

使组件过度依赖于其他组件是数十年来麻烦的源头,从Windows DLL Hell到iOS应用程序与竞争的崩溃处理程序。 所有最好的组件系统看起来都像Legos,最终用户在这里组装最小的依赖项。 尽可能地让你的内部框架只依靠Cocoa。 这有一些有形的devise影响:

  • 避免直接要求logging或分析引擎。 提供一个委托接口,可以适应调用者的引擎。
  • 避免琐碎的类别(只保存几行代码的方法)。 只需直接编写代码。
  • 避免添加不是很多买你的框架依赖。 不要添加AFNetworking只是为了通过NSURLConnection保存几行代码。 当然,如果你非常依赖另一个框架的function,那就不一样了。 但作为一个框架开发人员,在需要另一个框架之前,你的门槛应该是相当高
  • 强烈避免在构build或版本控制中很聪明。 我已经看到很多情况下,人们希望为应用程序级别的开发人员“自动”做所有事情,因此使系统变得非常复杂。 只要说“你需要链接这个和导入这个,并把它放在你的应用程序委托启动”。 不要创build复杂的构build和版本控制系统,以在第一个构build或两行初始化逻辑上保存2分钟。 这些东西炸毁,浪费时间来解决。 不要使用+load魔法。 只要说清楚一致。

当然,祝你好运。 支持其他开发者总是一个有趣的挑战。