3 回答
TA贡献1921条经验 获得超9个赞
如果您不需要同时使用两个框架中的类,并且您的目标是支持NSBundle卸载的平台(OS X 10.4或更高版本,没有GNUStep支持),并且性能对您来说确实不是问题,我相信你可以在每次需要使用一个类时加载一个框架,然后在需要使用其他框架时卸载它并加载另一个框架。
我最初的想法是使用NSBundle加载其中一个框架,然后复制或重命名该框架内的类,然后加载另一个框架。这有两个问题。首先,我找不到复制指向重命名或复制类的数据的函数,而第一个框架中引用重命名类的任何其他类现在将从其他框架引用该类。
如果有方法可以复制IMP指向的数据,则无需复制或重命名类。您可以创建一个新类,然后复制ivars,方法,属性和类别。还有更多的工作,但这是可能的。但是,您仍然会遇到引用错误类的框架中的其他类的问题。
编辑:C和Objective-C运行时之间的根本区别在于,据我所知,当加载库时,这些库中的函数包含指向它们引用的任何符号的指针,而在Objective-C中,它们包含字符串表示形式。 thsoe符号的名称。因此,在您的示例中,您可以使用dlsym在内存中获取符号的地址并将其附加到另一个符号。库中的其他代码仍然有效,因为您没有更改原始符号的地址。Objective-C使用查找表将类名映射到地址,并且它是1-1映射,因此您不能拥有两个具有相同名称的类。因此,要加载这两个类,其中一个必须更改其名称。但是,当其他类需要访问其中一个具有该名称的类时,
TA贡献1776条经验 获得超12个赞
使用唯一前缀为您的类添加前缀基本上是唯一的选择,但有几种方法可以减少繁琐和丑陋。还有就是选择一个长时间的讨论在这里。我最喜欢的是@compatibility_aliasObjective-C编译器指令(在此描述)。您可以使用@compatibility_alias“重命名”类,允许您使用FQDN或某些此类前缀命名您的类:
@interface COM_WHATEVER_ClassName : NSObject
@end
@compatibility_alias ClassName COM_WHATEVER_ClassName
// now ClassName is an alias for COM_WHATEVER_ClassName
@implementation ClassName //OK
//blah
@end
ClassName *myClass; //OK
作为完整策略的一部分,您可以为所有类添加前缀,例如FQDN,然后创建一个包含所有内容的标头@compatibility_alias(我想您可以自动生成所述标头)。
这样的前缀的缺点是你必须COM_WHATEVER_ClassName在除编译器之外的字符串中需要类名的任何东西中输入真正的类名(例如上面)。值得注意的是,@compatibility_alias是一个编译器指令,而不是运行时函数,因此NSClassFromString(ClassName)将失败(返回nil) - 您将不得不使用NSClassFromString(COM_WHATERVER_ClassName)。您可以使用ibtoolvia build阶段在Interface Builder nib / xib中修改类名,这样就不必在Interface Builder中编写完整的COM_WHATEVER _...
最后的警告:因为这是一个编译器指令(并且是一个模糊的指令),它可能无法跨编译器移植。特别是,我不知道它是否适用于LLVM项目的Clang前端,尽管它应该与LLVM-GCC(使用GCC前端的LLVM)一起使用。
TA贡献1825条经验 获得超6个赞
有些人已经分享了一些可能有助于解决问题的棘手和聪明的代码。一些建议可能有效,但所有这些建议都不太理想,其中一些建议非常难以实施。(有时丑陋的黑客是不可避免的,但我尽量避免使用它们。)从实际的角度来看,这是我的建议。
无论如何,请告知开发人员冲突的两个框架,并明确表示他们未能避免和/或处理冲突会导致您遇到真正的业务问题,如果解决这个问题,可能会导致业务收入损失。强调虽然在每个类的基础上解决现有的冲突是一个不那么具有侵入性的解决方案,但是完全改变它们的前缀(或者如果它们当前不是,那么使用它们,并且对它们感到羞耻!)是确保它们不会的最佳方法。再次看到同样的问题。
如果命名冲突仅限于一组相当小的类,请查看是否可以解决这些类,特别是如果您的代码之一未直接或间接使用其中一个冲突类。如果是,请查看供应商是否将提供不包含冲突类的框架的自定义版本。如果没有,请坦率地说,他们缺乏灵活性会降低您使用框架的投资回报率。不要因为在合理范围内咄咄逼人而感到沮丧 - 客户永远是对的。;-)
如果一个框架更“可有可无”,您可以考虑将其替换为另一个框架(或代码组合),无论是第三方还是自制程序。(后者是不受欢迎的最坏情况,因为它肯定会产生额外的业务成本,无论是开发还是维护。)如果你这样做,请告知该框架的供应商你决定不使用他们的框架的原因。
如果两个框架被认为对您的应用程序同样不可或缺,请探索将其中一个框架的使用分解为一个或多个单独进程的方法,也许可以通过DO进行通信,如Louis Gerbarg建议的那样。根据沟通的程度,这可能没有你想象的那么糟糕。我相信有几个程序(包括QuickTime)使用这种方法通过在Leopard中使用Seatbelt沙箱配置文件提供更细粒度的安全性,这样只允许代码的特定子集执行关键或敏感操作。性能将是一种权衡,但可能是您唯一的选择
我猜测许可费,条款和持续时间可能会阻止对这些点的即时行动。希望您能够尽快解决冲突。祝好运
- 3 回答
- 0 关注
- 1818 浏览
添加回答
举报