0

タイム プロファイラーが、アプリの実行速度が最も遅い場所を示しているため、アプリでマップ タイルの描画を高速化しようとしています。プロジェクト ファイルはここにあります。時間プロファイラーが最も遅いと言っている部分は、タイル オーバーレイの drawMapRect:zoomScale:inContext メソッドのこの部分です。

for (ImageTile *tile in tilesInRect) {
    CGRect rect = [self rectForMapRect:tile.frame];

    NSString *path = tile.imagePath;
    if (path) {
        UIImage *image = [UIImage imageWithContentsOfFile:path];

        CGContextSaveGState(context);
        CGContextTranslateCTM(context, CGRectGetMinX(rect), CGRectGetMinY(rect));

        float scale = (overZoom/zoomScale);

        CGContextScaleCTM(context, scale, scale);
        CGContextTranslateCTM(context, 0, image.size.height);
        CGContextScaleCTM(context, 1, -1);
        CGContextDrawImage(context, CGRectMake(0, 0, image.size.width, image.size.height), [image CGImage]);
        CGContextRestoreGState(context);
    }
}

私は、UIImages を使用してそれらをスケーリングすることが、物事を最も遅くしていると推測しています。これを高速化する方法、または描画をバックグラウンド スレッドに移動する方法はありますか? (アプリがタイルをロードするたびにマップのスクロールを停止しないため、drawMapRect はバックグラウンド スレッドで発生しませんが)

4

2 に答える 2

1

高速になるかどうかはわかりませんが、複数のタイルを扱っている場合は、操作を並列化してみてください。で多数のタイルをオフセットおよび/またはトリミングする必要がある場合はtilesInRect、Grand Central Dispatch を使用するNSOperationQueueか、これらを同時に複数実行してから、最終的な組み立てステップを行うことができます。

于 2013-08-20T15:55:42.053 に答える
1

はい、drawMapRectすでに複数のスレッドで実行されており、バックグラウンド スレッドから直接描画コードを呼び出すことは悪い習慣であり、速度や応答性は向上しません。コードのボトルネックはおそらく描画関数CGContextDrawImageであり、渡された mapRect と交差するタイルのみを描画しているとすでに確信している場合、できることはあまりないかもしれませんdrawMapRect:。ただし、UIImageのメソッドimageWithContentsOfFileを複数のスレッドから繰り返し呼び出すと、メソッドのように画像データがキャッシュされるとは思えませんimageNamed:。この問題を修正すると、速度が向上する場合があります。ただし、私の経験では、プロファイラーがその時間の大部分をdrawMapRect:方法。これはメイン スレッドから呼び出され、マップは引き続きユーザー インタラクションに応答するため、マップを最適化してもユーザー エクスペリエンスが大幅に改善されることはありません。

于 2013-08-21T04:15:20.683 に答える