NSOperation をサブクラス化して少しの作業を完了すると、非常に簡単にデッドロックすることがわかりました。以下に、完了しない理由を非常に簡単に理解できるおもちゃの例を示します。
デッドロックを防止する解決策を、呼び出し先ではなく、呼び出し元の観点から考えているようにしか思えません。たとえば、呼び出し元は、終了を待たずに実行ループを実行し続けることができます。操作中にメインスレッドがメッセージを同期する必要がある場合、操作サブクラスが実装できる標準的なソリューションがあるかどうか疑問に思っていますこのタイプのデッドロックを防ぎます。私は非同期プログラミングに足を踏み入れ始めたばかりです...
@interface ToyOperation : NSOperation
@end
@implementation ToyOperation
- (void)main
{
// Lots of work
NSString *string = @"Important Message";
[self performSelector:@selector(sendMainThreadSensitiveMessage:) onThread:[NSThread mainThread] withObject:string waitUntilDone:YES];
// Lots more work
}
- (void)sendMainThreadSensitiveMessage:(NSString *)string
{
// Update the UI or something that requires the main thread...
}
@end
- (int)main
{
ToyOperation *op = [[ToyOperation alloc] init];
NSOperationQueue *opQ = [[NSOperationQueue alloc] init];
[opQ addOperations: @[ op ] waitUntilFinished:YES]; // Deadlock
return;
}