Components.utils.unload()也卸载附属导入吗?



考虑以下示例:

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

卸载main.jsm是否也卸载sub.jsm,还是除main.jsm外还要卸载sub.jsm ?

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

不,它不会。

从加载器的角度来看,所有模块都是独立的和共享的。这是有意义的,因为所有模块在应用程序中只加载一次。当然,直到你的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中添加了另一个服务getter,例如:

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仍然引用那些字符串,因此你的模块不能完全垃圾收集,你的模块实例将有效地成为一个僵尸隔间。
  2. 因为所有其他插件和浏览器代码得到相同的服务。向其中添加新内容时可能会出现名称冲突。其他东西可能已经添加了uuid属性。

另外,你永远不应该Cu.unload不属于你的模块!

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

Cu.unload的操作没有影响。

相关内容

  • 没有找到相关文章

最新更新