为什么伞形框架不鼓励?

Ben*_*man 40 macos cocoa objective-c

我想分发框架A.框架A依赖于框架B.我希望我的框架的用户只需要包含框架A,但仍然具有对框架B的编程访问权限.

Apple使用"Umbrella Frameworks"的概念一直这样做,但是文档中有这个主题:

不要创建伞框架

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

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

Rob*_*ier 53

如果您是所有相关框架的唯一分发者,那么伞框架才有意义,您将把所有框架打包在一起作为单个版本化的包,它将一起升级.如果这是你的情况,那很好,但这是一个非常不寻常的情况.在可可开发世界中,除了苹果之外的任何人都处于这种状况.

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

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

对于第二点,如果您控制所有子框架的版本控制,则伞形框架才有意义.根据我的经验,尝试修补一个相互依赖的框架集几乎总是一个灾难.

由于系统的大小和普遍性,操作系统供应商有一个不寻常的情况.在一个尺度上有意义的事情往往在另一个尺度上没有意义.NSResponder对此完全正确.当您提供一个完整的,数千个包装环境时,权衡是不同的,这是为平台编写的每个程序的基础.但即便是苹果公司也只有少数大型伞形框架,它们总是围绕着它们提供和控制版本的库的包装.这主要是为了简化开发人员的工作,否则他们不得不追逐数十个库和框架来编译.没有第三方有这种情况,因此第三方很少需要这种解决方案.要求你的客户链接两个库是完全不同的,然后要求他们链接20.如果你提供20个框架,所有工作在一起,你控制,那么也许你应该使用一把伞,但也许你有太多的框架第三方.

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

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

  • 通过指示您的用户包含并链接到它.使用动态库(OS X和iOS 8),可以自己链接到系统级框架.但是第一个第三方框架,唯一合理的方法是在应用程序开发人员的控制下在应用程序级别完成所有链接.要为您的调用者自动链接,必须有一个依赖管理系统,并且没有内置的.CocoaPods提供一个,如果您和您的调用者都选择使用它.但必须在应用程序级别处理依赖项.您不能从调用者的框架中执行此操作. (3认同)

Jon*_*etz 5

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

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