重複の可能性:
Grand Central Dispatch (GCD) と performSelector - より詳しい説明が必要
メインスレッドで「もの」を実行するには、またはを使用する必要がありますdispatch_async
かperformSelectorOnMainThread
? 好ましい方法、正しい/または間違っている、および/またはベストプラクティスはありますか?
例:NSURLConnection sendAsynchronousRequest:urlRequest
メソッドのブロック内でロジックを実行しています。を提示するなど、メインビューに対して何かを行っているため、メインスレッドでUIAlertView
表示する必要があります。UIAlertView
これを行うには、次のコードを使用しています。
[NSURLConnection sendAsynchronousRequest:urlRequest queue:queue completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
// code snipped out to keep this question short
if(![NSThread isMainThread])
{
dispatch_async(dispatch_get_main_queue(), ^{
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Oops!" message:@"Some Message" delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil];
[alertView show];
});
}
}];
同じif(![NSThread isMainThread])
ステートメント内で、いくつかのカスタム メソッドも呼び出します。問題は、dispatch_async
上記で使用している方法を使用する必要があるか、performSelectorOnMainThread
それとも代わりに使用する方がよいかということです。たとえば、以下の完全なコード:
[NSURLConnection sendAsynchronousRequest:urlRequest queue:queue completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
// code snipped out to keep this question short
if(![NSThread isMainThread])
{
dispatch_async(dispatch_get_main_queue(), ^{
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Oops!" message:@"Some Message" delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil];
[alertView show];
// call custom methods in dispatch_async?
[self hideLoginSpinner];
});
// or call them here using performSelectorOnMainThread???
[self performSelectorOnMainThread:@selector(hideLoginSpinner) withObject:nil waitUntilDone:NO];
}
}];
参考までに、メイン スレッドでこれらのアクションを実行しないと、表示時に数秒の遅延が発生しUIAlertView
、デバッガに次のメッセージが表示されますwait_fences: failed to receive reply: 10004003
。これは、メイン スレッドの UI を変更する必要があるためであることがわかりました。