【问题标题】:Why are umbrella frameworks discouraged? [closed]为什么不鼓励使用伞式框架? [关闭]
【发布时间】:2011-11-14 00:00:56
【问题描述】:

我想分发框架 A。框架 A 依赖于框架 B。我希望我的框架的用户只需要包含框架 A,但仍然可以通过编程方式访问框架 B。

Apple 一直使用“Umbrella Frameworks”的概念来做这件事,但是文档中有这个主题:

不要创建伞式框架

虽然可以使用 Xcode 创建伞式框架,但 所以对于大多数开发人员来说是不必要的,不推荐使用。苹果 使用伞式框架来掩饰它们之间的一些相互依赖关系 操作系统中的库。在几乎所有情况下,您都应该 能够将您的代码包含在单个标准框架包中。 或者,如果您的代码足够模块化,您可以创建 多个框架,但在这种情况下, 模块将是最小的或不存在的,不应保证 为他们制作一把雨伞。

为什么不鼓励这种方法?是什么让它成为 Apple 的框架相互依赖问题的一个很好的解决方案,而不是我的?

【问题讨论】:

  • 我也想知道这个。当框架和项目的数量增加时,使用 git 存储库、依赖项目中的符号链接、框架/标题搜索路径以及所有有趣的东西设置自动构建可能会变得相当麻木。
  • 您在没有证据的情况下假设伞形框架“解决 Apple 问题的好方法”。我不知情的看法是相反的情况:将 iOS 与旧的 OSX 或新版本的 OSX 与旧版本进行比较,我看到诸如 CoreGraphics 之类的框架将 从伞形框架中移出 到独立框架中。我认为“雨伞”的想法是缓解 Cocoa 成长之痛的一个不错的组合,但绝不是“解决苹果问题的好方法”;也许他们是在警告你不要让自己陷入同样的​​困境。
  • 我投票结束这个问题,因为这个话题太老了。目前,iOS SDK 8.0 及以上版本,提供动态框架和快捷语法。所以,这个问题不再有用了。

标签: objective-c macos cocoa


【解决方案1】:

在 Apple 的案例中,他们交付了大量代码,而且这些子框架通常是单独修改的。如果您要交付多个框架,那么您可能想要继续制作一个伞式框架。如果没有,您可能不需要麻烦。

【讨论】:

  • 这使它看起来只是一个规模问题。如果它对许多框架来说都是一个很好的解决方案,那么为什么对一些框架来说不是一个很好的解决方案呢?这就像说只有在您拥有大量代码时,OO 设计才是一个好主意。是的,这对这种情况很有用,但即使你只有几个类也很好。
  • 如果集装箱船能很好地处理成吨的货物,为什么它就不能很好地处理几袋杂货呢?
  • 看,我真的不想在这里陷入类比战争。我的主要问题是:我想将多个框架作为一个框架分发。 Apple 有一个很好的解决方案,但他们不鼓励使用它。为什么?对这个问题的一个好的回答将告诉我一个伞式框架有什么问题,它只适用于 Apple 的框架。您的回答解释了为什么伞形框架对 Apple 有利,但您没有解释为什么它们对我不利。
  • @NSResponder 伞形框架的使用与您分发的包的大小无关。我会说这对 Apple 来说是可以接受的,因为这些框架纯粹是通过它们的分发机制进行分发的,因此冲突在某种程度上是可以预测的。换句话说,您不太可能在您的应用程序中无意中包含冲突的 Apple 框架,但认为您的框架的用户可能会单独包含您的基础依赖项之一的冲突版本并不是不现实的。想象一下,如果你有 100 个伞形框架。
【解决方案2】:

一个问题是框架 B 的版本现在与框架 A 的版本相关联。这在某些情况下可能是您想要的,而在其他情况下可能不是。如果框架 B 可能被一个也想使用框架 A 的应用程序独立使用,那么该应用程序可能会发现自己处于 A 中包含的 B 版本不是它需要或想要的版本的情况。

框架 B 是应用程序可以独立于 A 使用的框架吗?如果是这样,那么您可能会遇到这种情况。如果 B 是 A 之外不可用的框架,那么您不应该遇到这种情况。

【讨论】:

  • 这是一个很好的观点,谢谢。就我而言,这不是问题,但我当然可以看到这是一个因素。
【解决方案3】:

仅当您是所有相关框架的唯一分发者时,伞形框架才有意义,并且您将把所有框架打包成一个版本化的包,然后一起升级。如果这是你的情况,那很好,但这是一个非常不寻常的情况。在 Cocoa 开发世界中,除了 Apple 以外的任何人都处于这种情况是非常不寻常的。

首先,伞式框架只有在您是给定框架的唯一分发者时才有意义。例如,假设您想将 libcurl 作为伞形框架的一部分。现在,其他一些打包者也希望将 libcurl 作为其伞形框架的一部分。现在我们有一个链接时冲突,它可能导致链接错误或更糟糕的未定义的运行时行为。我自己追过这些。他们非常不愉快。避免这种情况的唯一方法是每个框架/库只有一个版本。伞式框架鼓励相反的情况。

即使您只是将自己的代码分解为子片段,这也意味着其他供应商可能会在他们自己的伞形框架中使用您的子框架,从而导致同样的问题。请记住,如果您说作为第三方可以使用伞式框架,那么其他供应商也可以。

对于第二点,伞式框架只有在您控制所有子框架的版本控制时才有意义。根据我的经验,尝试修补一组相互依赖的框架几乎总是一场灾难。

由于系统的规模和普遍性,操作系统供应商遇到了不寻常的情况。在一个尺度上有意义的事情往往在另一个尺度上没有意义。 NSResponder 对此完全正确。当您提供一个完整的、数千个软件包环境时,权衡是不同的,该环境是为平台编写的每个程序的基础。但即使是 Apple 也只有少数几个大型伞式框架,而且它们始终是它们提供和控制版本的库的包装器。这主要是为了简化开发人员的工作,否则他们必须追逐数十个库和框架才能编译一些东西。没有第三方有这种情况,所以很少有第三方需要这个解决方案。要求您的客户链接两个库与要求他们链接 20 个库是完全不同的。如果您提供 20 个可以协同工作并且您可以控制的框架,那么也许您应该使用保护伞,但也可能您的框架太多第三方。

我在这里的大部分讨论都是针对 OS X。在 iOS 上,这对第三方来说不是问题。由于肯定会发生冲突,静态库绝不能链接其他静态库。

理论上,我在这里讨论的大多数问题基本上都是链接器的技术限制。链接器没有很好的方法来管理库的多个版本,因此冲突是一个严重的问题。 .NET 程序集试图为此提供更多的灵活性。我对 .NET 开发不够熟悉,无法说出这是否成功。我对大型多组件系统的经验是,更简单、不太灵活的解决方案最适合大多数问题。 (不过,草总是更绿……)

【讨论】:

  • 很好的解释,谢谢:)
  • 如果我只想让我的框架使用第三方框架怎么办?如何确保 我的 用户也链接到它?
  • 通过指示您的用户包含并链接到它。使用动态库(OS X 和 iOS 8),您可以自己链接到系统级框架。但首先是第三方框架,唯一明智的做法是在应用程序开发人员的控制下在应用程序级别完成所有链接。要为你的调用者自动链接,必须有一个依赖管理系统,并且没有内置的。如果你和你的调用者都选择使用它,CocoaPods 提供了一个。但是必须在应用程序级别处理依赖关系。您不能从调用者的框架中做到这一点。
猜你喜欢
  • 2015-02-03
  • 1970-01-01
  • 1970-01-01
  • 2012-09-07
  • 2012-10-03
  • 2011-10-23
  • 2019-04-01
  • 2018-11-26
  • 1970-01-01
相关资源
最近更新 更多