同様の質問が何度か寄せられていることは知っていますが、この特定の問題を解決する方法を理解するのに苦労しています。これまでのところ、私が行ったことはすべてメイントレッドで実行されています。しばらく時間がかかる操作を実行する必要があることがわかりました。操作中に HUD をディスプレイに追加し、操作が完了するとフェードアウトしたいと考えています。
GCD について多くのことを読んだ (そしてかなり混乱した) 後、最も簡単な方法は、時間のかかるメソッドを NSInvocationOperation で呼び出し、それを新しく作成した NSOperationQueue に追加することであると判断しました。これは私が持っているものです:
[self showLoadingConfirmation]; // puts HUD on screen
// this bit takes a while to draw a large number of dots on a MKMapView
NSInvocationOperation *operation = [[NSInvocationOperation alloc] initWithTarget:self
selector:@selector(timeConsumingOperation:)
object:[self lotsOfDataFromManagedObject]];
// this fades the HUD away and removes it from the superview
[operation setCompletionBlock:^{ [self performSelectorOnMainThread:@selector(fadeConfirmation:) withObject:loadingView waitUntilDone:YES]; }];
NSOperationQueue *operationQueue = [[NSOperationQueue alloc] init];
[operationQueue addOperation:operation];
これにより、HUD が表示され、マップ上にドットの描画が開始され、その操作が完了すると、HUD がフェードアウトすると予想されます。
代わりに、HUD を表示し、マップ上にドットの描画を開始し、ドットを描画しながら HUD の方向にフェードアウトします。私の NSLogs によると、HUD をフェードするメソッドを呼び出す前に約 4 分の 1 秒の遅延があります。その間、ドットの描画はさらに数秒間続きます。
HUD をフェードアウトする前にマップの描画が完了するまで待機させるにはどうすればよいですか?
ありがとう
追加するために編集:
次の変更を加えた後、ほとんど成功しています。
NSInvocationOperation *showHud = [[NSInvocationOperation alloc] initWithTarget:self
selector:@selector(showLoadingConfirmation)
object:nil];
NSInvocationOperation *operation = [[NSInvocationOperation alloc] initWithTarget:self
selector:@selector(timeConsumingOperation:)
object:[self lotsOfDataFromManagedObject]];
NSInvocationOperation *hideHud = [[NSInvocationOperation alloc] initWithTarget:self
selector:@selector(fadeConfirmation:)
object:loadingView];
NSOperationQueue *operationQueue = [[NSOperationQueue alloc] init];
NSArray *operations = [NSArray arrayWithObjects:showHud, operation, hideHud, nil];
[operationQueue addOperations:operations waitUntilFinished:YES];
奇妙なことに、最初に timeConsumingOperation を呼び出し、次に showLoadingConfirmation、次に fadeConfirmation を呼び出しているようです。これは、これらのメソッド内で起動される私の NSLogs によるものです。
画面に表示される動作は次のとおりです。ドットが描画され、それに応じてマップがズームを調整し (timeConsumingOperation の一部)、HUD が画面に表示され、その後何も表示されません。timeConsumingOperation が完了するまで showLoadingConfirmation は発生せず、fadeConfirmation はまったく発生していないように見えますが、3 つの NSLog はすべて即座に表示されます。
これは非常に奇妙に思えますが、timeConsumingOperation の完了時に何かを発生させる方法があることを示唆しているようにも見えます。
これを追加してみました:
[operationQueue setMaxConcurrentOperationCount:1];
そしてこれも:
[showHud setQueuePriority:NSOperationQueuePriorityVeryHigh];
[operation setQueuePriority:NSOperationQueuePriorityNormal];
[hideHud setQueuePriority:NSOperationQueuePriorityVeryLow];
しかし、それらは何の違いもないようです。