5

我的应用程序有一个插件系统,允许我的用户编写他们自己的插件,这些插件在运行时加载。通常这很好,但在某些情况下,两个插件使用相同的库,这会导致这两者之间发生冲突。

例子:

插件 A想要使用TouchJSON来处理 JSON,因此创建者将 TouchJSON 代码添加到插件源中,它被编译并链接到插件二进制文件中。后来插件 B也想使用相同的库,并且完全相同。现在,当我的应用程序加载这两个不同的插件时,它会检测到这一点并发出如下警告:

CJSONScanner 类在 [path_to_plugin_a] 和 [path_to_plugin_b] 中都实现了。将使用两者之一。哪一个是未定义的。

由于我的应用程序只是加载插件并确保它们符合某个协议,因此我无法控制加载哪些插件以及两个或多个是否使用同一个库。

只要两个插件使用完全相同版本的库,这可能会起作用,但是一旦一个插件中的 API 发生更改,就会出现一堆问题。

对此我能做些什么吗?

4

2 回答 2

4

捆绑加载系统无法和平解决名称冲突。事实上,我们被告知要确保问题不会发生,而不是如果发生了该怎么办。(显然,在你的情况下,这是不可能的)。

您可以提交有关此问题的错误报告。

如果这对您的应用程序绝对至关重要,您可能希望将包放在不同的进程中,并可能使用某种 IPCNSDistantObject将数据从您的程序传递到插件主机。但是,我相当肯定这是一个伤害包,所以如果您没有非常明确定义的接口来允许分发到不同的进程,这可能是一项艰巨的任务。

于 2011-06-14T14:13:23.670 回答
2

在单进程模型中,处理这个问题的唯一方法是确保共享代码(更准确地说,共享的 Objective-C 类)被加载一次。有两种方法可以做到这一点:

  • 将共享代码放入框架中。
  • 将共享代码放在可加载的包中,如果相关类不可用,则在加载插件时加载包(检查使用NSClassFromString())。客户端代码也必须使用NSClassFromString()而不是直接引用类。

当然,如果您无法控制插件,则无法强制执行这些方案中的任何一个。你能做的最好的就是提供适当的指导方针和可能的基础设施;例如,在第二种情况下,加载可以由应用程序处理,可能通过指定要检查的类和要加载的嵌入包的名称(如果插件的Info.plist 中不可用) 。

于 2011-06-14T14:32:45.150 回答