0

アプリのある時点で、サーバーからデータを取得するためにアプリを必要とするコードのリストを配置しました。このプロセスにはかなりの時間がかかる可能性があることを知っているので、画面が暗くなる読み込み通知を配置し、ラベルを配置することにしました。その中心に「サーバーからblablablaデータを読み込んでいます」と書かれています

問題は、サーバーからいくつかのデータ(JSONデータ)をロードする間に、JSON関数間で変更するコードを配置してもラベルが変更されないことです

これが私のコードです

[self.viewReportProduksi getDataReport];
                           [loadinglabel setText:@"Loading Chart Data from server . . ."];
                           [self.viewReportProduksi getChartData];
                           [loadinglabel setText:@"Loading Data Komisi from server . . ."];
                           [self.viewKomisi getDataKomisi];
                           [loadinglabel setText:@"Loading Bonus Data from server . . ."];
                           [self.viewBonus getDataBonus];
                           [loadinglabel setText:@"Loading Bonus Agen Data from server . . ."];
                           [self.viewBonusAgen getDataBonusAgen];
                           [loadinglabel setText:@"Loading Agent Reward Data from server . . ."];
                           [self.viewAgenReward getDataRewardAgen];

これらの「getXXXXXX」は、JSONが実行されるメソッドです。

論理的には、これによりアプリは進行状況がどこまで進んだかを示すことができます。しかし、ラベルは「サーバーからのチャートデータのロード」に固執し続け、コードに応じて変更されません。

メインスレッドとdispatch_queueの両方でこれを試しましたが、どちらも違いはありません

ありがとう

4

3 に答える 3

1

これは、メインスレッドにデータをロードしているためであり、メインスレッドは非常にビジーであるため、表示が更新されることはありません。

データの読み込みを別のスレッドに移動し、たとえば、更新情報を含む通知をメインスレッドに送信する必要があります。

于 2012-05-10T07:19:34.760 に答える
1

問題は、すべてのグラフィックの更新がメインスレッドで行われることです。したがって、コードのブロック全体が完了するまで、ディスプレイ上で何も変更されません。これは、すべてのデータの読み込みをバックグラウンドで実行する必要がある場合だと思います。最大限の柔軟性を得るには、NSBlockOperationsの負荷を使用します。

まず、ステータステキストを更新するためにメインスレッドで実行するメソッドが必要です。

-(void) updateStatusWithString: (NSString*) message
{
    [loadingLabel setText: message];
    // might want to do other stuff e.g. if you have fully loaded the data
}

次に、メソッドがすべてのデータを順番にロードする代わりに、フェーズごとにNSBlockOperationを作成し、それを操作キューに追加します。

-(void) loadData
{
    NSBlockOperation* block1 = [NSBlockOperation blockOperationWithBlocK: ^()
    {
        [self performSelectorOnMainThread: @selector(updateStatusWithString:)
                               withObject: @"Loading chart data from server"
                            waitUntilDone: NO];
        [self.viewReportProduksi getChartData];
    }];
    NSOperationQueu* queue = [[NSOperationQueue alloc] init];
    [queue addOperation: block1];

    NSBlockOperation* block2 = [NSBlockOperation blockOperationWithBlocK: ^()
    {
        [self performSelectorOnMainThread: @selector(updateStatusWithString:)
                               withObject: @"Loading Data Komisi from server"
                            waitUntilDone: NO];
        [self.viewKomisi getDataKomisi];
    }];
    [block2 addDependency: block1];
    [queue addOperation: block2];

    // etc for all the other blocks
}

各操作は前の操作に依存しているため、次々に実行されますが、バックグラウンドスレッドで実行されます。操作と操作キューを使用すると、GCDよりも利点があります。

  • を使用して、操作間の依存関係を簡単にモデル化できます-addDependency:
  • 操作には、キャンセルのメカニズムが組み込まれています。ユーザーが途中でアプリを終了することにした場合は、

    [queue cancelAllOperations];
    

    開始されていないキューのすべての操作はキャンセルされます。

于 2012-05-10T09:03:30.363 に答える
0

私はあなたがそのようなことをするべきだと思います:

 - (void)firstPart {
    //This is main thread
    [loadinglabel setText:@"Loading Chart Data from server . . ."];
    [NSThread detachNewThreadSelector:@selector(getChartData) toTarget:self.viewReportProduksi withObject:nil];
}

 - (void)getChartData {
    //this is an extra thread
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
    //Your loading code
    [self performSelectorOnMainThread:@selector(secondPart) withObject:self waitUntilDone:NO];
    [pool drain];
 }
 - (void)secondPart {
        [loadinglabel setText:@"Loading Data Komisi from server . . ."];
        [NSThread detachNewThreadSelector:@selector(getDataKomisi) toTarget:self.viewKomisi withObject:nil];
}

等々...

于 2012-05-10T08:19:50.430 に答える