Components.utils.import/unload のメモ
Gecko 7.0 から Components.utils.unload() というメソッドが実装された。
詳細は上の記事を見るべきだが、挙動としては、
- Components.utils.import() で load したモジュール(のオブジェクト)を unload する
- メソッドを呼び出した時点では、unload されたモジュール(のオブジェクト)への参照は消えない
- 次に Components.utils.import() を呼び出した際に、新しく load されたモジュール(のオブジェクト)への参照に切り替わる
といった具合になっている。
Components.utils.import() には省略可能な第2引数があって、第2引数にオブジェクトを渡してやると、そのオブジェクトに新しいメンバが追加され、そのメンバがモジュールへ参照するようになる。
で、Components.utils.unload() 後に参照がどうのこうのとあって、気になって調べてみた。
サンプルコード
以下のコードを Firefox*1 の Scratchpad にて、chrome権限にて実行した
let a = {}; Components.utils.import("resource://gre/modules/XPCOMUtils.jsm", a); alert(a.XPCOMUtils.hogehoge);//undefined a.XPCOMUtils.hogehoge = "hogehoge"; alert(a.XPCOMUtils.hogehoge);//"hogehoge" Components.utils.unload("resource://gre/modules/XPCOMUtils.jsm");//unload alert(a.XPCOMUtils.hogehoge);//"hogehoge" Components.utils.import("resource://gre/modules/XPCOMUtils.jsm"); alert(a.XPCOMUtils.hogehoge);//"hogehoge" Components.utils.import("resource://gre/modules/XPCOMUtils.jsm", a); alert(a.XPCOMUtils.hogehoge);//undefined
結果
- Components.utils.import() の第2引数にオブジェクトを指定している場合、Components.utils.unload() を経ても、メンバの保持するモジュールへの古い参照はそのまま
- unload後の Components.utils.import() の際に、第2引数に初回の load 時に指定したオブジェクトを渡してやると、新しい参照へと切り替わる
その他
JSコードモジュール内のオブジェクトを nsIObserverService とかでオブザーバとして登録してる場合、Components.utils.unload() の際に、登録解除する手段が無いので、nsIWeakReference とかで弱参照にした方がいいんじゃないか?