這是一個奇怪的。我的應用程序將一個關閉消息發送給一個控制硬件設備的對象,並將一個完成塊作爲參數。關閉消息返回一個BOOL,取決於它是否能夠立即完成關閉。所以YES意味着它現在完成了,NO表示它將在稍後完成時調用完成處理程序。Objective-C完成塊導致額外的方法調用?
這裏的主控制器的代碼:
- (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;
}
這裏的設備控制器的代碼:
- (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;
}
怪異的部分是關閉的消息被髮送兩次。這些都是NSLog的消息:
shutdownWithCompletionHandler: Wait for reset
applicationShouldTerminate: waiting for reset
applicationShouldTerminate: completionBlock
shutdownWithCompletionHandler: shutdown now
所以完成塊的運行之後,我最終回到了設備對象的shutdownWithCompletionHandler:
方法。爲什麼?
編輯:嗯。 [[NSRunningApplication currentApplication] terminate];
是否會導致 applicationShouldTerminate:
再次被調用?我認爲它必須。是否有更好的方式在完成處理程序中退出應用程序?
非常好,謝謝! – Flyingdiver
無賴。這實際上並不奏效。這會導致運行循環進入NSModalPanelRunLoopMode,這意味着我的應用程序沒有在運行循環中獲取它的AsyncSocket調用,所以我無法與設備進行通信以使其關閉。我必須將其移至另一個運行循環,這比避免第二次調用的值得多。 – Flyingdiver
我從AsyncSocket的Run Loop版本切換到GCD版本,現在我可以在終止處於掛起狀態時完成設備控制器代碼。 – Flyingdiver