2

マップに約 3000 の MKOverlay を追加しています。スレッドを使用してパフォーマンスを向上させる方法を探しているので、ユーザーはオーバーレイが追加されている間にマップを移動できます。オーバーレイは、マップの領域内のものだけから始めて、順次追加されることが望ましいです。私はGCDでこれらの行に沿って何かを試しました:

- (MKOverlayView*)mapView:(MKMapView*)mapView viewForOverlay:(id)overlay {
    __block MKPolylineView* polyLineView;

    //do the heavy lifting (I presume this is the heavy lifting part, but 
    // because this code doesn't compile, I can't actually *test* it)
    // on a background thread
    dispatch_async(backgroundQueue, ^ { 
        polyLineView = [[[MKPolylineView alloc] initWithPolyline:overlay] autorelease];
        [polyLineView setLineWidth:11.0];

        //if the title is "1", I want a blue line, otherwise red
        if([((LocationAnnotation*)overlay).title intValue]) {
            [polyLineView setStrokeColor:[UIColor blueColor]];
        } else {
            [polyLineView setStrokeColor:[UIColor redColor]];
        }

        //return the overlay on the main thread
        dispatch_async(dispatch_get_main_queue(), ^(MKOverlayView* polyLineView){
            return polyLineView;
        });
    });
}

しかし、GCD ブロックはvoidパラメーターと戻り値の型で定義されているため、このコードは機能しません。行に互換性のないポインター型のエラーが表示されますreturn。ここに欠けているもの、またはこれをスレッド化する別の方法はありますか? それとも、オーバーレイ追加プロセスのパフォーマンスを向上させるまったく別の方法でしょうか? すべての助けに感謝します!

編集:

問題は、実際にここにオーバーレイを追加する場所ではないことがわかりました。

for(int idx = 1; idx < sizeOverlayLat; idx++) {
    CLLocationCoordinate2D coords[2];
    coords[0].latitude = [[overlayLat objectAtIndex:(idx - 1)] doubleValue];
    coords[0].longitude = [[overlayLong objectAtIndex:(idx - 1)] doubleValue];

    coords[1].latitude = [[overlayLat objectAtIndex:idx] doubleValue];
    coords[1].longitude = [[overlayLong objectAtIndex:idx] doubleValue];

    MKPolyline* line = [MKPolyline polylineWithCoordinates:coords count:2];
    [line setTitle:[overlayColors objectAtIndex:idx]];

    [mapViewGlobal addOverlay:line];
}

ここで 3000 をすべて追加すると、おそらく 100 ミリ秒かかります。最初に示した方法で、実際にオーバーレイを作成するところが (おそらく) 時間がかかる部分です。

4

1 に答える 1

0

あなたが望むものとコンパイラができることの間には少しギャップがあります。を呼び出しているときdispatch_asyncは、実際には CPU に「ここに、このコードのチャンクがあり、ユーザー インターフェイス スレッドをブロックしないように、今ではなくいつでも実行したい」と伝えていることになります。ただし、メソッドはnowに戻る必要があります。バックグラウンドスレッドで何かを作成する方法はまったくありません。何かを返す必要があるため、戻る前にそれを待つ必要があるためですmapView:viewForOverlay:

このメソッドは、GCD やバックグラウンド コードを使用する場所ではありません。あなたの問題が一度に多数のオーバーレイを追加することである場合、すべてのオーバーレイをたとえば 100 のチャンクに分割し、各バッチ間で 100 ミリ秒の遅延でそれらをマップに追加します。

于 2012-02-22T18:44:39.523 に答える