私は、アプリの 1 つでパフォーマンスの問題を突き止めようと取り組んでいます。発生しているように見えるのは、UIImageView が画像をレンダリングするのに数秒かかる場合があり、コードの記述方法が原因で、メイン スレッドがブロックされることです。
私は、遅い画像が網膜解像度のプログレッシブ JPEG であるという事実に問題を突き止めました。何らかの理由で、ファイルが特定のサイズに達すると、JPEG のデコードは非常にコストのかかる操作になります。
とにかく、単純なテスト アプリケーションを作成する過程で、描画イベントにかかる時間を計る方法がわからないことに気付きました。明らかにメイン スレッドがブロックされているため、実行ループの繰り返しの時間を試してみることにしました。残念ながら、それは少しハックになってしまいました。関連するコードは次のとおりです。
///////////////
//
// This bit is used to time the runloop. I don't know a better way to do this
// but I assume there is... for now... HACK HACK HACK. :-)
buttonTriggeredDate_ = [NSDate date];
[[NSRunLoop mainRunLoop] performSelector:@selector(fire:) target:self argument:[NSNumber numberWithInt:0] order:1 modes:[NSArray arrayWithObject:NSDefaultRunLoopMode]];
///////////////
NSString* path = [[NSBundle mainBundle] pathForResource:imageName ofType:type];
self.imageView.image = [UIImage imageWithContentsOfFile:path];
コールバックは次のとおりです (ハックです!):
- (void)fire:(NSNumber*)counter {
int iterCount = [counter intValue];
NSLog(@"mark %d", iterCount);
NSTimeInterval interv = [[NSDate date] timeIntervalSinceDate:buttonTriggeredDate_];
// We really need the second pass through - if it's less than X, assume
// it's just that first runloop iteration before the draw happens. Just wait
// for the next one.
if (iterCount < 1) {
iterCount++;
[[NSRunLoop mainRunLoop] performSelector:@selector(fire:)
target:self
argument:[NSNumber numberWithInt:iterCount]
order:1
modes:[NSArray arrayWithObject:NSDefaultRunLoopMode]];
} else {
self.statusDisplay.text = [NSString stringWithFormat:@"%@ - Took %f Seconds",
self.statusDisplay.text,
interv];
}
}
それで、私の質問は、基本的に、これをどのように行うのですか? さまざまな画像をドロップしてベンチマークを実行し、これを実行するのにかかる時間を大まかに把握できるようにしたいと考えています。また、適度に一貫性があり、ジッターがないことも望んでいます。
うーん、UIImageView をサブクラス化し、時間を記録するだけでよいでしょ[super drawRect:frame]
うか。
あなたならどうしますか?