iPhone SDK アプリ高速化のための Tips

domo Todo開発で実践してみた Tipsです。

1. 必要なときに必要なオブジェクトだけを生成する。

 domo のテーブルセルオブジェクトは、アイコンやテキストラベルなどたくさんの UIオブジェクトを持ちます。これらのオブジェクトのうち Todoタイトルやカラーラベルは常に表示するオブジェクトですが、タグやメモはオプションであるため、Todoによっては表示しません。
 前者のオブジェクトはセルの生成時に一緒に生成し、後者は必要になった時点で生成するようにしています(遅延生成)。こうすることで不要なオブジェクトを生成する時間とメモリ両方のコストを下げることができます。

2. 生成したオブジェクトはできる限り再利用する

 生成したオブジェクトは、将来再利用する可能性が高いのであればリリースせずに、保持し続けます。UIオブジェクトの場合、不要な場合は HIDDEN状態にしています。
 このやり方はメモリを食うため、メモリ消費量の大きなオブジェクトには向いていませんが、ラベルなどの小さな UIオブジェクトがたくさんある場合、オブジェクト生成の時間コスト削減に効果があります。

1と 2 のポリシーを実践すると、以下のようなコードになります。このコードは Todoセルの soonを表す UILabelオブジェクトの表示ロジックを簡略化したものです。soonはオプションなので、オブジェクト生成を必要になるまで遅延しています。また、不要な場合であってもリリースせずに非表示にし、再度必要になったときに表示しています。

UILabel* soonlabel = (UILabel*)[self.contentView viewWithTag:SOON_TAG];	

if (!todo.isSoon) {
	soonlabel.hidden = YES;  // Todoが soonでない場合は soonラベルオブジェクトを隠す。
                                 // soonラベルオブジェクトが未生成(soonlabel == nil)の場合は何もしないことになる。
} else {
	if (soonlabel == nil) {
            // soonlabelオブジェクトラベルが存在しない場合はオブジェクトを生成
            soonlabel =[[[UILabel alloc]init] autorelease];	
            soonlabel.tag = SOON_TAG;
            [colorLabel addSubview:soonlabel];
	}
	soonlabel.hidden = NO;		
}

3. 計測する

 iPhoneに限った話ではありませんが、処理の高速化には計測が重要です。計測してみてはじめて本当のボトルネックが明らかになることが多いためです。
 domo Todo+では当初、カレンダーの表示に時間がかかっており、UIButtonなどのオブジェクトがたくさんあるせいだと思っていました。しかし、実際に計測してみると、たしかに UIオブジェクトの生成にも時間はかかっていたのですが、その他に Todoの締め切り日とカレンダーの日付の照合処理に思った以上に時間がかかっていること、不要な描画処理を行っていることがわかりました。これらの処理を見直すことで、30%近い高速化ができました。