ここは奇妙なものです。私のアプリケーションは、完了ブロックを引数として、ハードウェアデバイスを制御するオブジェクトにシャットダウンメッセージを送信します。シャットダウンメッセージは、すぐにシャットダウンを完了できたかどうかによって、BOOLを返します。したがって、YESは完了したことを意味し、NOは後で完了時に完了ハンドラを呼び出すことを意味します。ここでObjective-C補完ブロックが余分なメソッド呼び出しを引き起こしますか?
は、メインコントローラのコードです:
- (BOOL)shutdownWithCompletionHandler:(void (^)(void))handler
{
if (busy)
{
self.completionBlock = handler;
[self stopDevice];
NSLog(@"shutdownWithCompletionHandler: Wait for reset");
return NO;
}
NSLog(@"Stoker: shutdownWithCompletionHandler: shutdown now");
return YES;
}
奇妙な部分は、シャットダウンメッセージが2回送信されるということです。
- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender
{
BOOL shutdownNow = [theStoker shutdownWithCompletionHandler:^(void)
{
NSLog(@"applicationShouldTerminate: completionBlock");
[[NSRunningApplication currentApplication] terminate];
}];
if (!shutdownNow)
{
NSLog(@"applicationShouldTerminate: waiting for shutdown");
return NSTerminateCancel;
}
return NSTerminateNow;
}
ここでは、デバイス・コントローラ・コードです。これらはのNSLogメッセージです:
shutdownWithCompletionHandler: Wait for reset
applicationShouldTerminate: waiting for reset
applicationShouldTerminate: completionBlock
shutdownWithCompletionHandler: shutdown now
だから、完了ブロックを実行した後、私は戻って、デバイスオブジェクトのshutdownWithCompletionHandler:
方法で終わります。どうして?
編集:Hmmm。 [[NSRunningApplication currentApplication] terminate];
は applicationShouldTerminate:
を再度呼び出しますか?私はそれが必要だと思います。補完ハンドラでアプリを終了するより良い方法はありますか?
ありがとうございました! – Flyingdiver
Bummer。これは実際には機能しません。これにより、実行ループがNSModalPanelRunLoopModeに入ります。これは、アプリケーションが実行ループでAsyncSocket呼び出しを取得しないため、デバイスと通信してシャットダウンすることができないことを意味します。私は別の実行ループに移す必要があります。これは、2回目の呼び出しを避ける価値があるよりも多くの作業です。 – Flyingdiver
私は、AsyncSocketのRun LoopバージョンからGCDバージョンに切り替えました。これで、終了が保留されている間にデバイスコントローラコードを完成させることができます。 – Flyingdiver