2009-09-24 31 views
0

我有一个适用于Mac OS X的应用程序,它支持打算同时加载的插件。其中一些插件是在Cocoa框架的基础上构建的,可以在一个插件中接收更新,而不是另一个。鉴于Objective-C当前的函数调度方法,任何插件对给定Objective-C例程的任何调用都将每次都进入相同的例程。这意味着插件A可以在插件B中找到自己的,并带有一个简单的Objective-C调用!显然,我们正在寻找的是每个插件都与它自己的框架版本进行交互。 Ihavebeenreading一些对Objective-C和这种特殊的需求,但还没有找到它最终的解决办法呢。Objective-C函数调度冲突;或者,如何实现“命名空间”?

更新:上面我用的是“框架”的误导性:该框架是一个静态链接库,内置到需要它的插件(一个或多个)。然而,Objective-C处理分派的方式,即使这些静态链接的不同代码碎片也会在Objective-C调度程序中混合,导致意想不到的后果。

更新2:我对answer provided here仍然有点模糊,因为它似乎没有像未经证实的假设那样提出解决方案。

+0

请参阅HTTP提出的想法的衍生物://计算器。com/questions/178434/what-is-the-best-way-to-solve-an-objective-c-namespace-collision – 2009-09-25 00:02:48

回答

0

我不认为我理解你对“插件A可以发现自己在插件B中”的评论。我猜你的意思是说,一旦你加载了一些依赖框架,那么每个人都会使用它而不是加载它们,这是正确的。这是正确的,你是否有类似命名空间的东西。

这是一个是否需要插件的OpenSSL的一个版本,你会面临同样的问题,而另一个插件所需的OpenSSL的另一个版本。您不能加载两个提供相同符号的库。

我理解这个问题吗?各种插件需要不同的,不兼容的相同框架版本?如果可能的话,我的方法是将框架更改为静态库并将您的插件静态链接到其框架。如果你没有在插件之间共享框架,那么框架确实不是你想要的。你只想编译代码(静态链接)。整个框架的重点是分享。

+0

就是这样 - 如果库静态链接,你也要烤面包; Objective-C处理调度的方式*一切*由单个调度程序处理,因此两个完全不同的,100%静态链接的插件可能会发现自己无意中调用了彼此的例程。 – fbrereto 2009-09-24 23:48:51

1

你不能做到这一点(至少不平凡),Objective-C的目前还没有命名空间的概念,并且运行时只提出一个单一的(全球)调度表。

注意,这不是唯一的Objective-C的,甚至是基于C的插件相当平凡相互之间也可以打电话,因为一切都在同一个地址空间。不可否认,如果您担心意外执行该操作的可能性较小,这是因为两级命名空间,但如果某个插件显式地尝试输入另一个代码,那么这些命令将无法保护您。

如果你真的想隔离插件,你运行加载插件代码,让你的应用程序执行本身和辅助应用程序之间的RPC可以创建单独的辅助程序。例如,这是Safari在Snow Leopard上以64位操作系统所做的工作。这种方法有许多好处,但实施起来相当复杂,你必须自己推出大部分。