ios - 多个框架和公共(public)库

标签 ios xcode ios8 cocoapods ios-frameworks

使用iOS 8, Xcode 6

假设我有2个动态框架frameworkAframeworkB,它们都依赖于libC。另外,我有一个同时使用frameworkAframeworkB的应用程序。我最初的想法是使frameworkAframeworkB框架成为框架,而libC为子框架。但是,Apple建议不要使用伞形框架,此post描述了由于潜在的链接程序冲突问题,为什么伞形框架不是一个好主意。

我的第二个选择是使用cocoapods(这仍然是新功能,因此在细节上有点模糊)将libC用作pod,然后将其编译为frameworkAframeworkB。但是,在我看来,这两个框架仍然具有自己的libC副本。由于该应用程序同时使用两个框架,这还会导致链接程序冲突问题吗?有没有更好的方法来解决此问题?

更新
@Rob我从事的项目确实需要复杂的依赖关系管理,但是我在问题中保持问题域简单,以试图更好地理解使用cocoapods如何以及是否可以通过伞形框架帮助解决链接程序冲突问题。我与一组开发人员一起工作,这些开发人员编写库,并且可以相互依赖提供基础版本API的彼此的基础库。我们需要将尽可能少的库打包并交付给使用该库构建应用程序的其他组织,而它们的关键要求之一就是我们要提供一个动态框架。

最佳答案

解决大多数问题的最佳方法是将所有代码放入项目中并进行编译。当您遇到使该问题成问题的特殊问题时,则应考虑其他解决方案,例如静态库,最后是框架。

如果您的代码库包含需要不同构建要求的代码段,则静态库可能很有意义。如果所有部分都具有相同的build设置,则只需将它们从“公共(public)”目录“添加文件”到您的项目中,然后构建您的项目。如果您的构建时间非常重要,并且某些部分永远不会更改,并且您希望能够“清理”而不重建这些部分,则静态库可能会很有吸引力。但是请等到开始出现该问题后再进行复杂的多包项目。

如果您出售封闭源代码库,那么框架将非常有吸引力。出于引起注意的原因,您应强烈避免添加第三方依赖项。如有必要,最好的方法是帮助客户将所有组件打包为框架,并在最后将它们链接起来。但是,这增加了很多烦恼。因此,请确保您确实需要该第三方产品。

如果您有大量可重用的代码,并且它们的生命周期与主要产品分开,那么您也可能会考虑使用框架。但同样,请保持简单。避免在其中包含第三方内容,如果您必须包含第三方内容,则请消费者在最后将其链接。

(顺便说一句,这不是一个新的解决方案,顺便说一句。使用curl时,如果需要SSL,还需要下载并构建OpenSSL并将它们自己链接在一起。Curl不内置OpenSSL。)

但是在大多数情况下,这都是过分的。不要跳转到框架。不要跳到图书馆。只需将所有代码放入项目中并进行编译即可。您的问题中有90%将消失。特别是iOS项目通常没有那么大。框架要解决什么问题?

如果您的组织中有很多重复使用的代码,那么我听说很多团队都可以使用内部CocoaPods来管理它。但这只是为了简化代码 checkout 。它仍然全部进入一个项目,然后将其一起编译为一个二进制文件。无需任何框架。对于某些以前确实很痛苦的问题,动态框架是一个很好的功能。但是,在大多数情况下,它们只是寻找问题的复杂性。

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

编辑:(您陷入了这个“特殊问题”,所以让我们来谈谈。我在大型的多团队Mac和iOS开发环境中也做了很多年。我们几乎尝试了每种不同的解决方案,包括Frameworks 。它们只是iOS上的新功能。)

在您描述的组织中,我强烈建议将每个依赖项包装为自己的框架(AFNetworking,JSONKit等),并将每个组件包装为框架,然后让应用程序开发人员最后将所有这些链接在一起。这样,它与其他动态库(libcurl,openssl等)相同,后者要求应用程序开发人员将所有内容链接在一起。

在任何情况下,动态框架都不应包括否则可能需要的其他框架(即,框架绝不应该打包“第三方”内容)。那会爆炸的。您不能使它不爆炸。您可能会肿,构建冲突或运行时冲突。这就像合并冲突。在某个时候,开发人员必须做出选择。应用程序级链接正在做出这种选择。

从Windows DLL Hell到具有竞争崩溃处理程序的iOS应用程序,数十年来一直是使组件过度依赖于其他组件的麻烦之源。所有最好的组件系统看起来都像Legos,最终用户在那里组装具有最小依赖性的小块零件。尽可能使您的内部框架仅依赖于Cocoa。这对设计产生了明显的影响:

  • 避免直接需要日志记录或分析引擎。提供一个可以适应调用者引擎的委托(delegate)接口(interface)。
  • 避免琐碎的类别(仅保存几行代码的方法)。只需直接编写代码即可。
  • 避免添加对您没有太大影响的框架依赖项。不要仅仅为了在AFNetworking上保存几行代码而添加NSURLConnection。当然,如果您严重依赖另一个框架的功能,那就不一样了。但是,作为框架开发人员,在需要另一个框架之前,您的阈值应该很高。
  • 强烈避免在构建或版本控制中变得聪明。我见过太多的情况,人们想让应用程序级开发人员将所有事情“自动化”,从而使系统真正变得复杂。只需说“您需要链接并导入它,并将其放入您的应用程序委托(delegate)启动中。”不要创建复杂的构建和版本控制系统,以在第一代构建或两行初始化逻辑上节省2分钟的时间。这些东西炸毁,浪费了很多时间来解决。不要因+load魔术而变得聪明。只是要清楚和一致。

  • 当然,祝您好运。支持其他开发人员始终是一个有趣的挑战。

    关于ios - 多个框架和公共(public)库,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28246818/

    相关文章:

    iphone - iOS 的自定义控件或框架

    ios - Windows/Linux iOS App开发(无需编译)

    ios - 使用 NSLayout 设置 UILabel 的 X 和 Y 值

    ios - 使用 Phonegap 安装 Cordova 插件 - no Cordova.plist

    ios - 如何使用 NSLog 调试 iOS 8 扩展?

    ios - 在 SpriteKit 中使用 CAGradientLayer?

    xcode - 无法将 cv.h 添加到项目中

    ios - 将 NSArray 拆分为 NSString

    swift - [__NSCFTimer copyWithZone :]: unrecognized selector sent to instance

    javascript - iOS 8 css 旋转元素消失