この記事は、@astronaughtsさん主催のTitanium mobile “early” Advent Calendar 2012に参加して書いております。6日目(11/6)担当でございます。
やってはいけないTi.App.addEventListener
addEventListenerをTi.Appに設定する場合、
Ti.App.addEventListener("save_astronaughts",function(){
Ti.App.info("I'll save you!!");
});
な感じで書きます。
が、注意しなければならないのは、この処理が複数回呼ばれるような場所にあると、呼ばれるたびにeventが追加されてしまいます。同じイベント名だからといって上書きされません。
私にも、windowをopenしてcloseしたらそのwindow内で定義したevent全て消えてくれるのかと思ってた時期がありました。。。
前の日の記事でもaddEventListenerについて書かれていますが、
var win = Ti.UI.createWindow({});
win.addEventListener("save_astronaughts",function(){
Ti.App.info("I'll save you!!");
});
これだとwinをcloseすればOKですが、Ti.Appだとグローバルに定義している形になり、残ってしまうようですね。
複数定義してしまってても、アプリ自体はすんなり動いたりするので、見落としてました。
二重登録の対策
もちろん、複数呼ばれる場所に書かない、というのが基本ですが、私の場合、もう書いてしまって定義場所を移動しづらかったので、ラッパーを作って対策してみました。
// Ti.App.addEventListener の二重登録防止関数
Ti.App.ael = function(listener_name,callback){
// 登録済みの場合追加しない
if(Ti.App.in_array(listener_name,Ti.App.listeners)){
return false;
}
// イベントを配列に登録
Ti.App.listeners.push(listener_name);
// イベント追加
return Ti.App.addEventListener(listener_name, callback);
}
定義済みのイベント名をグローバルな配列listenersに登録して、定義済みかのチェックを行っています。コード内のin_arrayはこちら。何かの公開コード(忘れた。。。)に定義されていたのを拝借しております。
Ti.App.in_array = function(needle, haystack, argStrict) {
var key = '',
strict = !! argStrict;
if (strict) {
for (key in haystack) {
if (haystack[key] === needle) {
return true;
}
}
} else {
for (key in haystack) {
if (haystack[key] == needle) {
return true;
}
}
}
return false;
}
何かもっと素敵な対策方法あれば教えてください!
次は
@daoki2 さんお願いします。