3

私は、アプリの 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]うか。

あなたならどうしますか?

4

1 に答える 1

0

問題の間違った部分の時間を計ろうとしている可能性があります。ご想像のとおり、問題はデコードにある可能性が最も高いです (おそらくメモリの割り当てとコピーにもあります)。問題が最後の「描画」ステップ自体にあるとは考えにくいです。

これは、Instruments が構築されている種類の問題です。Instruments を起動し、ホットスポットを探します。

CALayer考えられる解決策として、Instruments がデコードがブロックしていることを示している場合は、画像をビューに配置する前に、バックグラウンド スレッドで画像をレンダリングすることを検討してください。

于 2012-07-13T01:34:03.613 に答える