TitaniumのWindowは再利用するべきか

何度も同じ内容のWindowをcreateしまくっていいのだろうかと言うこと。

例えば何かボタンを押すたびに以下のようなコードを実行するとする。

var newWin = Ti.UI.createWindow({
    url: 'hogehoge.js',
    title: 'ほげほげ',
});
Ti.UI.currentTab.open(newWin);

これで新しい画面に遷移した後、元の画面に戻ってまたボタンを押したら同じ内容のWindowがまた作られて、リソースを圧迫していくのではないかということが心配になる。
都度createしないで再利用すべきなのだろうか。

再利用しないとWindowはどんどん増えていくのか?

この懸念に関してはWindowがフォーカスを失ったときにcloseされるので問題ないようだ。

hogehoge.jsに以下のようなコードでWindowオブジェクトが破棄される様子を確認できる。

win = Ti.UI.currentWindow;

win.addEventListener('open', function(e) {
  Ti.API.info('opened');
  Ti.API.info(win.checkReuse);
  win.checkReuse = 'is reuse?';
});
win.addEventListener('close', function(e) {
  Ti.API.info('closed');
  Ti.API.info(win.checkReuse);
});

これで画面遷移を繰り返すと以下のようなログが表示される。

[INFO] opened
[INFO] <null>

[INFO] closed
[INFO] is reuse?

[INFO] opened
[INFO] <null>

再度表示したときのcheckReuseの内容はnullになっている。

つまり一度フォーカスを失って二度目に表示したときに最初に表示したときの状態を維持してない。
二度目の表示の際に作り直されている。

再利用はできるのか?

生きているオブジェクトに参照が残っていれば破棄されないので、他のオブジェクトのプロパティとしてくっつけておけば再利用は可能。

mainWin = Ti.UI.currentWindow;
  if (!mainWin.hogehogeWin) {
    mainWin.hogehogeWin = Ti.UI.createWindow({
      url: 'hogehoge.js',
      title: 'ほげほげ',
    });
  }
  Ti.UI.currentTab.open(mainWin.hogehogeWin);

呼び出し元のコードを上記のようにして実行すると以下のようなログになる。

[INFO] opened
[INFO] <null>

[INFO] closed
[INFO] is reuse?

[INFO] opened
[INFO] is reuse?

Windowオブジェクトのcloseイベントは呼び出されるが、checkReuseの内容は生きている。
つまり再度表示したときも以前の状態を保持しており、破棄はされていないことがわかる。

あら、破棄されて無くてもcloseイベントは呼ばれるのですな。

明示的に再利用するべきか?

作成と破棄を繰り返す方がコード的にはシンプルになるので基本的には再利用しないに一票。

あとはパフォーマンス的に何か問題が出たとき考えるのがよいかと。

参考

一番下の方にUIオブジェクトの仕組みについて書いてある。

Windowごとにjsファイルを分けておくと、Windowが閉じたときに即座にリソースがクリーンナップされて、リソースの節約になるよって書いてあるね。

2011/01/30追記

実はメモリリークする問題がある模様。

では再利用するようなコードを書いた方がいいのかと言うと、試してみたらそうしても遷移を繰り返すとメモリ消費が増えていくのでダメみたい。
急激に増えていくわけでもないので、これは割り切るしかないのかな。

TitaniumのWindowは再利用するべきか” に対して1件のコメントがあります。

コメントは受け付けていません。