Components.utils.unload()是否也卸载了辅助导入?

时间:2014-07-01 07:13:24

标签: javascript firefox firefox-addon firefox-addon-restartless

考虑以下示例:

Components.utils.import('chrome://something/content/main.jsm');

// inside main.jsm
Components.utils.import('chrome://something/content/sub.jsm');

除了main.jsm之外,卸载sub.jsm是否也会卸载sub.jsmmain.jsm是否会被卸载?

注意:卸载是Firefox bootstrapped插件中shutdown()的一部分。

1 个答案:

答案 0 :(得分:1)

不,它不会。

所有模块都是独立的,并从加载器的角度共享。这是有道理的,因为所有模块在应用程序中只加载一次。那么,直到你Cu.unload,当然;虽然该模块的后续Cu.import然后会像初始加载一样再次加载它。

因此,在访问它的所有代码之间共享一个模块。这意味着将发生以下情况:

other.jsm

EXPORTED_SYMBOLS = ['shared'];
shared = {abc:123};

bootstap.js

// Initial load of shared.jsm
Cu.import(".../other.jsm");
// Will be seen by all other modules, since this is shared. 
shared.def = 345;

// Will not propagate, as the top-level name shared is just a reference
// in the current scope, initially holding a reference to the object from shared,
// but now overriden.
shared = "string";

Cu.import(".../main.jsm");

main.jsm

// Since the module was already loaded before, the loader will not load it again
// but instead just use provide the references. 
Cu.import(".../other.jsm");

Cu.reportError(shared.abc); // 123
Cu.reportError(shared.def); // 456

这可以非常方便,例如当你需要一个中央位置来跟踪/共享/缓存内容时,但在关机时内存泄漏方面也有点危险。

如果你是将另一个服务获取者添加到Services.jsm,例如:

Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/XPCOMUtils.jsm");

XPCOMUtils.defineLazyServiceGetter(Services, "uuid",
                                   "@mozilla.org/uuid-generator;1", "nsIUUIDGenerator");

现在出现问题有两个原因:

  1. Services将(最初)保留对这些字符串参数的引用。这些字符串字符串由您的模块拥有。 Cu.unload你的模块不会完全破坏你的模块实例,因为Services仍然引用那些字符串,因此你的模块不能完全被垃圾收集,你的模块实例将有效地成为Zombie Compartment。< / LI>
  2. 由于所有其他附加组件以及浏览器代码都获得相同的服务。添加新内容时可能会出现名称冲突。其他东西可能已经添加了uuid属性。
  3. 另外,你永远不应该Cu.unload不属于你的模块!

      

    卸载是Firefox bootstrapped插件中shutdown()的一部分。

    Cu.unload的操作无关紧要。它总是会一样的。