• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Re: NSApplication terminate: behavior
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: NSApplication terminate: behavior


  • Subject: Re: NSApplication terminate: behavior
  • From: Camillo Lugaresi <email@hidden>
  • Date: Sat, 21 Jan 2006 00:01:33 +0100

On 20/gen/06, at 23:23, Andreas Färber wrote:

Am 20.01.2006 um 22:15 schrieb Camillo Lugaresi:

I did try calling stop: from applicationShouldTerminate: returning NS***Cancel and, like I said in the above quote, it worked in taking me back to my Main method. However I did not find an easy way to terminate (as opposed to "terminate:") the Cocoa NSApplication, leaving the windows, application menu etc. on screen until after my main application was already exited.

I think stop just sets a flag that tells run to stop looping; if you call it in applicationShouldTerminate, you're already inside terminate and exit is going to be called anyway. You need to prevent terminate from being called,

a) If in ***shouldTerminate I return ***Cancel (NSApplicationTerminateReplyCancel?) it does not terminate;
b ) if I return *Now it terminates immediately, not returning to Main as usual, and
c) if I return *Later the main loop is halted, not returning to Main.
If I call stop: before I return Cancel, I get out of the run loop and back to Main but the application is still alive, just no runloop active.

Ah, righ it makes sense that calling stop and then cancelling the termination attempt gets you out of the run loop. I must have misread you before.


Are you saying that you already implemented everything the documentation says (calling app delegate methods, document-based app methods, sending the notification, all in the right order), and things still aren't getting cleaned up correctly?
There's also the possibility that it's not a Cocoa problem at all. For example, AppKit might not be destroying windows when the app quit, instead relying on a lower layer mechanism (such as an atexit callback that tells the window server that the app is going down, so it can destroy all of its windows?).


However, the important application-specific cleanup is done inside delegate methods. As long as you're calling them as stated in the documentation, documents will be closed, preferences will be saved, etc.

Could you please explain this further? What delegates exactly are you referring to? The AppKit NSApplication documentation says this about terminate:


<<This method is typically invoked when the user chooses Quit or Exit from the application’s menu. Each use of terminate: invokes applicationShouldTerminate: (page 144) to notify the delegate that the application will terminate. If applicationShouldTerminate: (page 144) returns NO, control is returned to the main event loop, and the application isn’t terminated. Otherwise, the document controller of the application (if one exists) is asked to check its documents and, if there are unsaved changes, ask the user to save those changes. Then, this method posts an NSApplicationWillTerminateNotification (page 147) to the default notification center. Don’t put final cleanup code in your application’s main() function—it will never be executed. If cleanup is necessary, have the delegate respond to applicationWillTerminate: (page 145) and performcleanup in that method. >>

The YES or NO is actually replaced by the three enum values referenced somewhere above, as specified in the delegates' documentation.

Now are these the two delegates that you say I should call myself? Don't they just enable *me* to react to these events?

Yes, although I think there might be other parts of Cocoa that depend on the NSApplicationWillTerminateNotification. I was under the impression that you were trying to load an existing Cocoa application, in which case ensuring that delegate methods are called as specified in the docs is crucial.


And how exactly would I invoke them anyway?

For example,

	delegate = [NSApp delegate];
	if (delegate) reply = [delegate applicationShouldTerminate:NSApp];

...etc. Use NSNotificationCenter to send the NSApplicationWillTerminateNotification.
You should probably also go throught the window list and close each window, eg:


	NSArray *windows = [NSApp windows];
	unsigned count = [windows count];

	while (count--) {
		[[windows objectAtIndex:count] close];
	}

Finally, I guess you can try calling [NSApp release];

Right now when experimenting with stop: I do not know what exactly to do from there! That's one of the questions. The documentation does not say "call this, do that", the above quote and other places just describe that terminate: is calling the two mentioned delegates, but does not say anything else it might be doing.

Yes, I don't see the details are documented anywhere. However, since you have full control of the application, you have the advantage that you don't have to worry about all possible side-effects that might not happen, but only the ones which are important to you.


And to make it very clear I do not want to call anything from my Main method that again would result in a call to exit() on the side of Cocoa. Just close and release the windows, views, controls, menu and let me return to my NSAutoreleasePool wrapper and other managed non-Cocoa objects.

The things I outlined above should be a start. Once you have implemented them, see what's missing.
Unfortunately, I think it will have to be a process of trial and error unless someone who knows Cocoa's internals decides to shed some more light on the termination process.


You could also consider stopping the application right before terminate is called, then setting a breakpoint on objc_msgsend (and the other versions of that call) that logs each method call and then continues. That should give you a log of the methods called during terminate, which might be useful.

Camillo _______________________________________________
Do not post admin requests to the list. They will be ignored.
Cocoa-dev mailing list      (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden


  • Follow-Ups:
    • Re: NSApplication terminate: behavior
      • From: Andreas Färber <email@hidden>
References: 
 >NSApplication terminate: behavior (From: Andreas Färber <email@hidden>)
 >Re: NSApplication terminate: behavior (From: Camillo Lugaresi <email@hidden>)
 >Re: NSApplication terminate: behavior (From: Andreas Färber <email@hidden>)
 >Re: NSApplication terminate: behavior (From: Camillo Lugaresi <email@hidden>)
 >Re: NSApplication terminate: behavior (From: Andreas Färber <email@hidden>)

  • Prev by Date: value pattern bindings & date formatter?
  • Next by Date: Screensaver
  • Previous by thread: Re: NSApplication terminate: behavior
  • Next by thread: Re: NSApplication terminate: behavior
  • Index(es):
    • Date
    • Thread