0
-(void) test{
    for(Person *person in persons){
        __block CGPoint point;
        dispatch_async(dispatch_get_main_queue(), ^{
            point = [self.myview personToPoint:person];
        });
        usePoint(point); // take a long time to run
    }
}

personToPoint()ポイントを取得するにはメインキューで実行する必要があり、メソッドusePoint()はメインキューで実行する必要がなく、実行に時間がかかります。ただし、usePoint(point)dispatch_asyncを使用しているため、実行時にポイントに値が割り当てられていません。dispatch_syncメソッドを使用する場合、プログラムはブロックされます。割り当てられたポイントをどのように使用できますか?

更新:次のコードのパターンを実装する方法:

-(void) test{
    NSMutableArray *points = [NSMutableArray array];
    for(Person *person in persons){
        __block CGPoint point;
        dispatch_async(dispatch_get_main_queue(), ^{
            point = [self.myview personToPoint:person];
            [points addObject:point];
        });
    }
    usePoint(points); // take a long time to run
}
4

1 に答える 1

1

次のようなものが機能します。forループ全体を1つのdispatch_async()内に配置し、メインスレッドにすべてのusePoint()関数を一度にディスパッチさせることもできます。

-(void) test{
    for(Person *person in persons){
        dispatch_async(dispatch_get_main_queue(), ^{
            CGPoint point = [self.myview personToPoint:person];
            dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
                usePoint(point); // take a long time to run
            });
        });
    }
}

更新された質問の解決策:

上記と同じ基本パターンを使用します。つまり、メインスレッドで実行する必要のある作業をメインスレッドにディスパッチしてから、ディスパッチをメインスレッドディスパッチ内のデフォルトのワークキューにネストして戻します。したがって、メインスレッドがその作業を終了すると、時間のかかる部分を他の場所で実行するためにディスパッチします。

-(void) test{
    dispatch_async(dispatch_get_main_queue(), ^{
        NSMutableArray *points = [NSMutableArray array];
        for (Person *person in persons){
            CGPoint point = [self.myview personToPoint:person];
            [points addObject:[NSValue valueWithCGPoint:point]];
        }
        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
            usePoint(points); // take a long time to run
        });    
    });
}

オブジェクトではないため、にCGPoint'を追加できないため、コードにエラーがあったことに注意してください。NSArrayそれらをでラップしてから、NSValueでアンラップする必要がありusePoint()ます。NSValueiOSでのみ機能する拡張機能を使用しました。Mac OS Xでは、これをに置き換える必要があります[NSValue valueWithPoint:NSPointToCGPoint(point)]

于 2012-08-20T04:40:21.940 に答える