1

I want to save my data before terminating, so my AppControll class conforms the NSApplicationDelegate protocol, and declared the method; and in the interface builder I bound the window's delegate outlet to AppController, but I cannot get the method invoked.

Where I am wrong, what should I do?

Mohd Sadham
  • 435
  • 3
  • 19
  • 1
    @user408141: I notice (now) that @Firoze Lafeer added the [cocoa] and [osx] tags after the fact. Is that what you meant, or did you mean `UIApplicationDelegate` (Cocoa Touch)? – Peter Hosey Dec 01 '10 at 03:51

5 Answers5

11

Are you terminating the app from Xcode? Alternatively, is sudden termination enabled in your Info.plist?

Either of these will cause a SIGTERM signal to be sent to the application, terminating it immediately, with no chance for the NSApplication instance to send its delegate an applicationWillTerminate: message. (This is the point of sudden termination: Your app dies instantly. You can turn it off and on programmatically for times when this would be bad.)

Try quitting your application within itself (the Quit menu item in your Application menu), or using the Dock to quit it (right-click on your application's tile and choose “Quit”). As long as sudden termination is disabled (or never was enabled), either of these will cause your application object to send the applicationWillTerminate: message.

Also check that your delegate is getting sent other application-delegate messages, such as applicationWillFinishLaunching:, and make sure you hooked up the outlet in the correct nib (your MainMenu nib).

Peter Hosey
  • 95,783
  • 15
  • 211
  • 370
  • This is false. `SIGKILL` terminates an application instantly. `SIGTERM` does give a program the chance to handle termination. (But I don't know how to catch sigterm in a macOS application, either.) – Noah Nuebling Jul 10 '22 at 18:09
  • You'd need to use a signal handler. NSApplication theoretically could install one and catch `SIGTERM` to notify its delegate, but it doesn't (it only does that for the Quit Apple Event or the app's own Quit menu item). With no handler in place, `SIGTERM` terminates the process instantly. – Peter Hosey Jul 19 '22 at 22:14
4

Did you remember to add the handler to the application?

UIApplication *app = [UIApplication sharedApplication];
[[NSNotificationCenter defaultCenter] 
   addObserver:self
   selector:@selector(applicationWillTerminate:)
   name:UIApplicationWillTerminateNotification object:app];
William Niu
  • 15,798
  • 7
  • 53
  • 93
  • 4
    The documentation suggests that this is not necessary: http://developer.apple.com/library/ios/documentation/UIKit/Reference/UIApplicationDelegate_Protocol/Reference/Reference.html#//apple_ref/occ/intfm/UIApplicationDelegate/applicationWillTerminate: Note that it's documented as taking the UIApplication object, not an NSNotification, which suggests that the delegate method is not a notification handler. You should not need to observe for the notification to receive this message. And even in Cocoa, where it is a notification, you still don't need to explicitly observe for it. – Peter Hosey Dec 02 '10 at 21:24
  • @Peter I don't quite get you. How can a method receive notifications without subscribing to / observing any event? – William Niu Dec 03 '10 at 04:38
  • 2
    @William - because applicationWillTerminate: is part of the UIApplicationDelegate protocol, and will be invoked automatically by the system. I'm with Peter, this should not be needed. – James J Dec 03 '10 at 04:59
  • Wait a sec, the original question was talking about NSApplicationDelegate (not UIApplicationDelegate). How is this working? – James J Dec 03 '10 at 05:02
  • 1
    @William: In UIKit, it isn't a notification method. (In AppKit, it is.) The UIApplication object sends that message to its delegate. Just being the delegate should be enough. (In AppKit, it is—I know for sure that you do not need to explicitly add the NSApplication's delegate as an observer; in AppKit, being the delegate *is* enough.) – Peter Hosey Dec 03 '10 at 07:46
  • @jenningj: I'd say that's in doubt. See my comment on the question. – Peter Hosey Dec 03 '10 at 07:46
2

Is multitasking still enabled? That could be the problem - tapping the home button doesn't cause applicationWillTerminate: to be called if the app goes into the background.

James J
  • 6,428
  • 6
  • 35
  • 45
2

I'm assuming this question applies to macOS apps (as it mentions NSApplicationDelegate).

By default, Xcode 11 (and maybe earlier versions?) includes the NSSupportsSuddenTermination property in new applications' Info.plist file:

  ...
  <key>NSSupportsSuddenTermination</key>
  <true/>
  ...

This property is associated with the enableSuddenTermination and disableSuddenTermination pair of methods in the ProcessInfo (NSProcessInfo) class.

The relevant part of ProcessInfo documentation states:

Sudden Termination

macOS 10.6 and later includes a mechanism that allows the system to log out or shut down more quickly by, whenever possible, killing applications instead of requesting that they quit themselves.

Your application can enable this capability on a global basis and then manually override its availability during actions that could cause data corruption or a poor user experience by allowing sudden termination. Alternately, your application can just manually enable and disable this functionality.

In other words, when NSSupportsSuddenTermination is true, when the user tries to quit the application (directly or indirectly), macOS terminates it, instead of requesting it to quit. This bypasses any events that would otherwise be triggered during a regular quit request.

The good new is that you can either disable that in the Info.plist file, or manually override it, according to your application's needs, by calling ProcessInfo.processInfo.disableSuddenTermination().

Community
  • 1
  • 1
Andre Rodrigues
  • 2,214
  • 16
  • 14
0

In applicationWillFinishLaunching: add:

[[NSNotificationCenter defaultCenter]
    addObserver:self
    selector:@selector(applicationWillTerminate:)
    name:UIApplicationWillTerminateNotification object:nil];
JasonMArcher
  • 14,195
  • 22
  • 56
  • 52
Suresh Vutukuru
  • 211
  • 2
  • 8
  • copies existing answer above – Max MacLeod Dec 07 '15 at 16:54
  • 1
    @MaxMacLeod No reason for a downvote. Votes are supposed to tell the reader the quality of an answer and the user who seeks for help doesn't case if there is another answer with the same content or not. This answer is good and this answer is right and just because someone else was faster doesn't make this a bad answer. If duplication was a problem, it would be possible to flag posts as duplicate but as you can see, there is no duplicate flag. – Mecki Jun 06 '16 at 10:15
  • @Mecki you have some good points. Although in this case the duplicate answer was posted five years later. I'm happy to improve my SO behaviour. Could you reference any SO help links that back up your comment? – Max MacLeod Jun 06 '16 at 11:44
  • 1
    @MaxMacLeod E.g. http://stackoverflow.com/help/privileges/vote-down doesn't mention that you should down vote duplicate answers and you should also not downvote duplicate questions - rather flag them. And not even duplicate questions are such a big problem http://blog.stackoverflow.com/2010/11/dr-strangedupe-or-how-i-learned-to-stop-worrying-and-love-duplication/ As all answers are CC license, you are even explicitly allowed to re-use content of another answer in your own answer. If the answer was an exact, verbatim, one to one duplicate... but it isn't and great minds think alike ;-) – Mecki Jun 06 '16 at 12:05