我在这里重新阅读这篇文章:https://stackoverflow.com/a/24473888/1828637
并担心我是否做得对。这就是我卸货的方式:
所以我在每个窗口设置一些东西。并在关机时卸载它们。 (我不会在窗口关闭时卸载,我还没有找到需要,因为当它关闭时,我添加到它的所有内容都与关闭一起[例如我的变异观察者])。
下面的所有代码都是理论上的,变异的东西就是例子,因此可能存在拼写错误或错误。我想知道它背后的想法是否合适:
var unloadersOnShutdown = [];
var unloadersOnClose = [];
function startup() {
let DOMWindows = Services.wm.getEnumerator(null);
while (DOMWindows.hasMoreElements()) {
let aDOMWindow = DOMWindows.getNext();
var worker = new winWorker(aDOMWindow);
unloadersOnShutdown.push({DOMWindow: aDOMWindow, fn: worker.destroy});
}
}
function shutdown() {
Array.forEach.call(unloadersOnShutdown, function(obj) {
//should probably test if obj.DOMWindow exists/is open, but just put it in try-ctach
try {
obj.fn();
} catch(ex) {
//window was probably closed
console.warn('on shutdown unlaoder:', ex);
}
});
}
function winWorker(aDOMWindow) {
this.DOMWindow = aDOMWindow;
this.init();
}
winWorker.prototype = {
init: function() {
this.gMutationObserver = new this.DOMWindow.MutationObserver(gMutationFunc.bind(this));
this.myElement = this.DOMWindow.querySelector('#myXulEl');
this.gMutationObserver.observe(this.myElement, gMutationConfig);
if (this.DOMWindow.gBrowser && this.DOMWindow.gBrowser.tabContainer) {
this.onTabSelectBinded = this.onTabSelect.bind(this);
this.gBrowser.tabContainer.addEventListener('TabSelect', this.onTabSelectBinded, false);
}
},
destroy: function() {
this.gMutationObserver.disconnect();
if (this.onTabSelectBinded) {
this.gBrowser.tabContainer.removeEventListener('TabSelect', this.onTabSelectBinded, false);
}
},
onTabSelect: function() {
console.log('tab selected = ', thisDOMWindow.gBrowser.selectedTab);
}
};
var windowListener = {
onOpenWindow: function (aXULWindow) {},
onCloseWindow: function (aXULWindow) {
var DOMWindow = aXULWindow.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowInternal || Ci.nsIDOMWindow);
for (var i=0; i<unloadersOnClose.length; i++) {
if (unloadersOnClose.DOMWindow == DOMWindow) {
try {
unloadersOnClose.fn();
} catch(ex) {
console.warn('on close unloader:', ex);
}
unloadersOnClose.splice(i, 1);
i--;
}
}
},
onWindowTitleChange: function (aXULWindow, aNewTitle) {},
}
我认为一个问题是我没有使用DOMWindow
的弱引用,但我不确定。
答案 0 :(得分:2)
围绕卸载程序的想法似乎一般都没问题,但非常有限(仅适用于Windows)。
缺乏实施。例如。有一个很大的肥胖小虫:
unloadersOnShutdown.push({DOMWindow: aDOMWindow, fn: worker.destroy});
// and
obj.fn();
// or
unloadersOnClose.fn();
这会使用错误的winWorker.prototype.destroy
来调用this
。
i++
/ i--
循环也看起来,嗯...... "interesting"?!
另外,请记住可能存在微妙的泄漏,因此您应该考虑并测试Zombie compartments。
窗口不仅可以泄漏附件的部分内容(例如bootstrap.js
),而且还可以通过在附加组件中保留引用来泄漏关闭的窗口。当然,它不仅仅是你需要关心的窗户,而且还包括观察者,其他类型的(XPCOM)听众等。