Hatena::ブログ(Diary)

oct inaodu

 

2012-01-05

LinkStationのディスクチェック機能は異常ファイルが削除される

設定画面の[ディスク管理]-[ディスクチェック]を行うと、異常ファイルが見つかった場合、確認無く削除され消えます。復元はできません。単なるチェックかと思い軽い気持ちで実行すると驚きます。大量のファイルを失いました。機種はLS-QL/1Dです。サポートに確認しました。fsckと同じ動作だとのこと。僕の場合、ディスクチェックを行う前は「たまに遅いことはあっても全ファイルアクセスできる」という状況だったので、この時にまず一度ファイルを待避するべきでした。物理的なディスクチェックは毎夜行っていてエラーは見つかっていなかったので油断していました。

2011-04-05

iPad、GPU、テキストのレンダリング、チラつき


iPadで上のページを見ると、各Oの字が異なって見える。

3dのスタイルは、scale3d(1, 1, 1)とtranslate3d(0, 0, 0)で効果を無くしてる。

ちょっと滑らかで、細く見える。


画面内のGPUで描画している特定の要素に変更を加えると、全く異なる位置にあるGPUを使っていなくてz-indexの低い要素(具体的には画面上部のツールバー)がチラつくという現象が出た。

translate3d(0, 0, 0)を設定し、そちらもGPU描画に切り替えて回避した。


GPUは切り替わるときにチラつきが発生したり、1万ピクセル四方以上あたりの要素で描画が切れたり、通常とは違う挙動がいろいろある。

2011-02-01

Re: Date.now() しない throttle


同期的に大量に呼び出され、それを間引くことを考えてなかったす。

主にイベントの間引きに使ってた。

たしかにsetTimeoutで一定期間、処理をロックしちゃうとコスト低そうすね。


Function.prototype.throttle = function(threshold){
	threshold = threshold || 100;
	
	var me = this;
	var timer = null;
	return function(){
		if(timer != null)
			return;
		
		timer = setTimeout(function(){
			timer = null
		}, threshold);
		
		me.apply(this, arguments);
	};
}

インタフェースに使うときの反応を考えると、最初の呼び出しは同期にしたいな。

ノンブロッキングや処理のまとめは、また要件/背景が異なるので、別にdefer(JSDeferrdのファストウェイ的なもの)などを組み合わせるといい気がします。


Function.prototype.defer = function(){
	var me = this;
	return function(){
		var self = this;
		var args = arguments;
		var script = document.createElement('script');
		script.src  = 'data:text/javascript,';
		script.onload = function(){
			document.body.removeChild(script);
			
			me.apply(self, args);
		}
		
		document.body.appendChild(script);
	}
}

2011-01-31

iPad、画像リソースのメモリリーク

iPadSafariは、2カ所から画像のメモリに接続するとリークしガベージされない。

iOS、3.2、4.2.1、どちらも起きる。


例えば、2つのimg要素が同じsrcを設定すると、その画像リソースはページのリロードまで2度と離されない。

以下のサンプルは、画像ロードが途中で停止し、以降は新しい画像を表示できない。

デスクトップブラウザのように、別のimg要素でプリフェッチして、他のimg要素で表示する手法は使えない。


// imagesにsrcのリストを用意
var elmImage = document.body.appendChild(document.createElement('img'));
var elmOther = document.createElement('img');
(elmImage.onload = function(){
	document.title = images.length;
	
	// 2カ所からリンク
	elmOther.src = elmImage.src;
	
	if(images.length)
		elmImage.src = images.shift();
})();

またLast-Modifiedなどで、ブラウザキャッシュし、そのリソースを使った時もリークする。

大抵のウェブサーバーは、この挙動だけど。

ブラウザキャッシュがちょうど一杯になるか越えるぐらいの画像を用意して、以下を2度実行すると、最初のサンプルと同様に途中で停止する。

(画像が多すぎるとサイクルしてキャッシュヒットしなくなり、少なすぎると停止するまでの量にならないので実験する場合は注意)

この挙動は、yubichizで同じ箇所を繰り返し表示させているとロードが停止する現象などで確認できる。


// imagesにsrcのリストを用意
// images = images.concat(images); // これで2周しても可
var elmImage = document.body.appendChild(document.createElement('img'));
(elmImage.onload = function(){
	document.title = images.length;
	
	if(images.length)
		elmImage.src = images.shift();
})();

いろいろテストする場合は、iPadの設定からSafariキャッシュをクリアし、Safari再起動してから行うこと。


関連

img要素をたくさん生成できない問題の回避方法。使い終わったら、srcを空にする(data uri使わなくても大丈夫だったとおもう)。

canvasを併用していろいろやる方法は基本的に遅い。

data uri(base 64)は、もっと遅い。

実行間隔を調整する


密に処理が実行されてしまうのを避けるため、二つのかたちがあるとのこと。

下のデモ。

throttleは、0.5秒ごとに点の位置が変わる。

debounceは、0.5秒いると赤くなる。



throttle

ひとつ目は一定間隔以内の呼び出しは間引いて無視する方法。

イベントの発生頻度が多く、処理が重い場合に使う。

Function.prototype.throttle = function(threshold, alt){
	threshold = threshold || 100;
	
	var me = this;
	var last = Date.now();
	return function(){
		var now = Date.now();
		if(now - last < threshold){
			if(alt)
				alt.apply(this, arguments);
			return;
		}
		
		last = now;
		me.apply(this, arguments);
	};
}

debounce

もうひとつは、一定間隔呼び出されなかったときに、はじめて処理を実行する方法。

補完や通信、ツールチップマウスアウトでメニューを閉じる場合などに使う。

Function.prototype.debounce = function(threshold){
	var me = this;
	var timeout;
	
	return function(){
		var self = this;
		var args = arguments;
		
		if(timeout)
			clearTimeout(timeout);
		
		timeout = setTimeout(function(){
			me.apply(self, args);
			timeout = null; 
		}, threshold || 100); 
	};
}

2010-11-01

iPad、JailBreak後にインストールするアプリ

HTML + JavaScriptアプリケーションを開発するとき、メモリ残量を確認しながら動作をチェックしていってる。

JailBreak後、たぶんステータスバーをスライドして擦るとSBSettingsのメニューが出てくるので、[More]-[SBSettings Options]-[Statusbar Free Mem]から常に表示するようにする。

こうしておくと、30MBを下回ったあたりから動作が不安定になったりとか、そういうのがきちんとわかるようになる。


iPadは、アプリをたくさんインストールすると、アイコンが増えて何をするにも遅くなる。

開発テスト用のiPadに参考アプリを多数インストールすると、常識的なiPad環境より処理能力が劣ることになる。

そういうときはCategoriesでフォルダに入れたり、SBSettingsのHide Iconsからアイコンを減らして正常化したりする。


OpenSSHSSHサーバー。たぶん最初から入ってる。ログインパスワードの変更は忘れないように。
afc2addiFunBoxからファイルを直接受け渡すために。SCPよりも断然速い。iFunBoxと接続するときにiPadの電源を入れる必要はない。Applications(User)(/var/mobile/Applications)を参照すると、ランダムな記号フォルダ名がアプリ名に置き換えて表示される。GoodReaderなどに一括でPDFインポートするときに便利。/System/Library/Audio/UISoundsの音ファイルを聞いたり、/var/mobile/Library/Preferences/com.apple.springboard.plistを編集してダッシュボードのページを入れ換えたり、とにかくいろいろ使う。
Infiniboardダッシュボードを縦方向にもスクロールできるようにする。僕は各ページでジャンルを分けて縦に長く並べてる。使い始めは、ダッシュボードページング時に縦と横の操作ミスが発生するようになったけど(だからデフォルトできないようになってるんだな)、慣れたら大丈夫。アプリアンインストール時の挙動などが若干変。
Infinidockドックに並べられるアイコンの数を増やす。僕は8個まで置けるようにして、7個置いてる。1マスはページ間のアイコン移動時のテンポラリ領域になってる。そこに置いて、ページング(SprintBoard)して、そこから出す。
Browser Changerデフォルトブラウザの変更。僕はAtomicにしてる。
CyDeleteCydiaから入れたアプリをダッシュボードからダイレクトに削除できるように。
MultiIconMover複数のアイコンを一度に他のページに移動。アプリが多い場合は必須。どれかのアプリアイコンを長押し、移動したいアプリをタップでチェックしていく、どれかを移動、ホームボタン押下で移動を終了、チェックしたアプリが一括移動、という流れ。
SprintBoardダッシュボードを素早くページング。ドック上のページ一覧ドット部分をスライドしダッシュボードを移動できるようになる。これも最初は思ったように使えないけど、慣れると無い状態が考えられなくなる。
file:// for MobileSafariローカルファイルをSafariから開けるように。技術デモなどをiPadに入れて持ち運びデモしたりするのに使ってる。
Categoriesアプリフォルダ。フォルダにアプリドラッグで追加できなかったり、フォルダに入ったアプリをダイレクトにアンインストールできなかったり、そんなに使い勝手はよくない。普段使わない参考アプリアーカイブする目的で使ってる。ダッシュボードに置いておくとiPadが遅くなるから。
CategoriesSBたぶん、こっちも入れないとiPadでCategoriesがちゃんと動かない。
iPhone OS ThemeSBSettingsのスキン。
Proswitcherバックグラウンドアプリの管理。 http://rpetri.ch/repo/Cydia(apt)のソースに追加して、1.2~alpha~3をインストール。たぶんBackgrounderとかのコアも同時に入る。ホームボタン長押しで起動しているアプリのサムネイルが横方向に並び、選択起動や、上方向へのスワイプで終了させたりできるようになる。動きがきれい。
iFileiPad内を閲覧するファイラ。ファイルコピー、権限変更やplistファイルの確認/編集などに使う。有料で、よく動く。

上にはないけど、VNCサーバーとかRhinoネイティブアプリ(サンプル)とか常時モニタ出力(PCで表示)とか探すといろいろある。

位置情報が動作しないとか不具合が生じたら、 http://cydia.pushfix.info/aptリポジトリから修正パッチインストールすることで直るかも。