0

長いメインスレッド アクションの進行状況を表示するのに少し問題があります (メイン スレッドにある必要があります)。

アクションは、ボタンを押すことによって呼び出されます。

-(void)getCSVExport:(id)sender{
    ...
    NSString *filePath = [path stringByAppendingPathComponent:fileName];
    NSData *csvData = [NSData dataWithContentsOfFile:filePath];
    if (nil == csvData) {
       _progressView.hidden = NO;
       [self.view bringSubviewToFront:_progressView];
       _progressView.progress = 0;
       csvData = [self generateCSVExportForMonth:_monthToExportInt];
       [csvData writeToFile:filePath atomically:YES];
       _progressView.hidden = YES;
    }
    ...
}

関数内でgenerateCSVExportForMonth:、進行状況を で更新してい_progressView.progress = newValueます。

私は今2つの問題があります:

1) 呼び出しボタンを押すとgetCSVExport:、呼び出しが終了するまでボタンが強調表示されたままになります。2)progressViewは表示されず、それ自体を更新することは言うまでもありません。

情報: デバイスによっては、通話に 0.5 ~ 2 秒かかります。

私が間違っていたアイデアはありますか?

// 編集: backgroundThread を使用した新しいバージョン:

[self.view bringSubviewToFront:_progressView];
_progressView.progress = 0;
[self performSelector:@selector(assignCSVData:) onThread:[NSThread new] withObject:csvData waitUntilDone:YES];
_progressView.hidden = YES;

時間のかかる呼び出し:

-(void)assignCSVData:(NSData*)data{
    data = [self generateCSVExportForMonth:_monthToExportInt];
 }

これにより、performSelector呼び出し時にデッドロックが発生します。

4

1 に答える 1

2

問題は、メイン スレッドがブロックされていることです。GUI をフリーズさせたくないので、時間がかかる処理にバックグラウンド スレッドを使用するのはまさにそのためです。

CSV ファイルの解析などをメイン スレッドで行う必要ある理由がわかりません。バックグラウンドで実行する必要があります (または、フリーズした GUI のユーザー エクスペリエンスの悪さに耐えなければなりません)。

このようなものを実際に実装する方法はいくつかあります。

  • NSObjectの使用performSelectorInBackground:withObject:

    解析コードを別のメソッドに配置し、次を使用してバックグラウンド スレッドで開始します。

    [self performSelectorInBackground:@selector(parseMethod) withObject:csvData];
    

    そのメソッドの最後に、メイン スレッドで何らかのメソッドを呼び出して、解析が終了したことを通知します。

    [self performSelectorOnMainThread:@selector(parsingDone:) withObject:result waitUntilDone:NO];
    
  • Grand Central Dispatch (GCD)を使用して、ブロック構文を使用してバックグラウンドでコードを実行します。また、Objective-C と Cocoa API に慣れている場合は、非常に単純ですが、もう少し複雑な構文とセマンティクスについて説明します。

  • とを使用NSOperationNSOperationQueueます。おそらく、あなたの目的のために少しオーバーヘッドがあります。addOperationWithBlockただし、サブクラス化せずに呼び出すことで、新しい操作をキューに簡単に追加することもできますNSOperation

于 2013-04-03T12:13:25.713 に答える