0

重要な場合: - ストーリーボードを使用しています - コア データ - xcode 4.6

私のアプリには、特定のビュー用の UITableViewController があります。そのビューで、ユーザーがボタンをクリックすると、ソフトウェアはインターネット API からデータをダウンロードしてコア データに保存するいくつかのプロセスを実行します。これはリソースを大量に消費していると確信しているため、これらのプロセスを別のスレッドで完了しようとしています。

注: - レッグは取引所に依存するため、操作の順序があります。交換は種族やポジションによって異なります。順位は種族によって異なります。そうでなければ、すべてを非同期で実行していたでしょう。

問題: - グランド セントラル ディスパッチと仕事をするのはこれが初めてです。私はそれを正しく行っているかどうかわかりません。- データ処理をコメントアウトすると、UIProgressView が表示され、期待どおりに更新されます。データ処理が適切に行われると、システムが行き詰まりすぎて UIProgressView を表示することさえできなくなります。

ダウンロードと進行状況を管理する方法は次のとおりです。


- (IBAction)downloadNow:(id)sender {

[progressView setHidden:NO];
[progressView setProgress:0.1 animated:YES];

dispatch_sync(backgroundQueue, ^(void){
    [self saveRace];
    [self updateProgress:0.2];
});

dispatch_sync(backgroundQueue, ^(void){
    [self savePositions];
    [self updateProgress:0.3];
});

dispatch_sync(backgroundQueue, ^(void){
    [self downloadExchanges];
    [self saveExchanges];
    [self updateProgress:0.4];
});

dispatch_sync(backgroundQueue, ^(void){
    [self downloadLegs];
    [self saveLegs];
    [self updateProgress:0.5];
});

dispatch_sync(backgroundQueue, ^(void){
    Utilities *utilities = [[Utilities alloc] init];
    [utilities calculateStartTimes:race with:managedObjectContext];
    [self updateProgress:1.0];
});

}

  • (void)updateProgress:(double)completedPercentage { if (completedPercentage == 1.0) { [self goHome]; } else if ([importExchanges count] > 0) { [progressView setProgress:completedPercentage animated:YES]; } }

どんな助けでも大歓迎です。

4

1 に答える 1

2

メソッドdispatch_syncは呼び出し元のスレッドをブロックします。あなたの場合はメインスレッドだと思います。したがって、それらのdispatch_syncブロックを1つのdispatch_asyncブロックにラップする方が良いと思います.

例として:

dispatch_async(backgroundQueue, ^(void){
    [self saveRace];
    [self updateProgress:0.2];

    [self savePositions];
    [self updateProgress:0.3];

    [self downloadExchanges];
    [self saveExchanges];
    [self updateProgress:0.4];

    [self downloadLegs];
    [self saveLegs];
    [self updateProgress:0.5];

    Utilities *utilities = [[Utilities alloc] init];
    [utilities calculateStartTimes:race with:managedObjectContext];
    [self updateProgress:1.0];
});

その後、UI の更新であるため、progressView の更新をメイン スレッドでラップすることができます。

- (void)updateProgress:(double)completedPercentage {
    if (completedPercentage == 1.0) {
        [self goHome];
    } else if ([importExchanges count] > 0) {
        dispatch_async(dispatch_get_main_queue(), ^{
            [progressView setProgress:completedPercentage animated:YES];
        });
    }
}
于 2013-06-23T14:49:35.990 に答える