Objective-C termination block calling an extra method call?

It's weird here. My application sends a shutdown message to the object controlling the hardware device, with a termination block as an argument. The shutdown message returns BOOL, depending on whether it succeeded in shutting down immediately. Thus, YES means that it is done now, NO means that it will call the completion handler when it is done later.

Here is the main controller code:

- (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; } 

Here is the device controller code:

 - (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; } 

The strange part is that disconnect messages will be sent twice. These are the NSLog posts:

 shutdownWithCompletionHandler: Wait for reset applicationShouldTerminate: waiting for reset applicationShouldTerminate: completionBlock shutdownWithCompletionHandler: shutdown now 

So, after the completion block is executed, I will return to the shutdownWithCompletionHandler: object again. Why?

Edit: Hmmm. Does [[NSRunningApplication currentApplication] terminate]; applicationShouldTerminate: to call the call again? I think it should be. Is there a better way to exit the application in the completion handler?

+4
source share
1 answer

Since you found the root cause of your problem (calling terminate calls applicationShouldTerminate: , here's how to avoid it.

Instead of canceling the completion, return the NSTerminateLater when it shuts down later. Then, your completion block should call [NSApp replyToApplicationShouldTerminate:YES] to cause the completion without calling applicationShouldTerminate: again.

 - (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender { BOOL shutdownNow = [theStoker shutdownWithCompletionHandler:^(void) { NSLog(@"applicationShouldTerminate: completionBlock"); [NSApp replyToApplicationShouldTerminate:YES]; }]; if (!shutdownNow) { NSLog(@"applicationShouldTerminate: waiting for shutdown"); return NSTerminateLater; } return NSTerminateNow; } 
+5
source

All Articles