Go Back   MacRumors Forums > Apple Systems and Services > Programming > Mac Programming

Reply
 
Thread Tools Search this Thread Display Modes
Old Mar 1, 2006, 02:22 PM   #1
netytan
macrumors 6502
 
Join Date: May 2004
applicationWillTerminate

Hey guys,

I'm having a problem with applicationWillTerminate. What I need to do is run something once when the program exits, like applicationWillTerminate is supposed to do but it's not being called. I've set NSApp's delegate in the awakeFromNib of course but no luck.

I tried moving the delegation to other methods just to see what would happen and that triggers applicationWillTerminate, but, also crashes out with an error .

Will ALL the objects have there dealloc called when the program exits or is it a cold shutdown, giving the memory over to other processes?

If this is the case then this must happen after I/O has been dismantled because NSLog never displays anything in my tests, so confused . I don't do a lot with Cocoa because I generally have no need for GUI's so I work more with other languages. Is this a Newbie problem I'm having?

Thanks a lot,

Mark.
__________________
12" G4 IBook (1GHz) named Darwin: 60GB HardDrive, BlueTooth, Airport Extreme coming soon?
netytan is offline   0 Reply With Quote
Old Mar 1, 2006, 02:37 PM   #2
caveman_uk
Guest
 
caveman_uk's Avatar
 
Join Date: Feb 2003
Location: Hitchin, Herts, UK
In my apps I generally set the app delegate in the main controllers -init function. I can see why awakeFromNib should be a problem.

You don't generally put your code to release any retained objects in applicationWillTerminate - you put it in the controller class's -dealloc method. I'm not sure from your description if that's what you've done. Whilst I think when an app closes it releases everything even if it's not explicitly released in the code, it's good practise to release anything you've retained. BTW you call 'release' not 'dealloc' on an object to destroy it but in the class itself any tidy up code is in the 'dealloc' method. Odd but true...

Personally I've never needed to have an applicationWillTerminate method as all my tidy-up code is in the -dealloc method of the main app controller.
caveman_uk is offline   0 Reply With Quote
Old Mar 1, 2006, 02:53 PM   #3
netytan
Thread Starter
macrumors 6502
 
Join Date: May 2004
Quote:
Originally Posted by caveman_uk
In my apps I generally set the app delegate in the main controllers -init function. I can see why awakeFromNib should be a problem.

You don't generally put your code to release any retained objects in applicationWillTerminate - you put it in the controller class's -dealloc method. I'm not sure from your description if that's what you've done. Whilst I think when an app closes it releases everything even if it's not explicitly released in the code, it's good practise to release anything you've retained. BTW you call 'release' not 'dealloc' on an object to destroy it but in the class itself any tidy up code is in the 'dealloc' method. Odd but true...

Personally I've never needed to have an applicationWillTerminate method as all my tidy-up code is in the -dealloc method of the main app controller.
Normally no but I'm embedding an interpreter written in C and I only want it to be shutdown when the application is finished running. Adding it to the dealloc or retain methods in the main document class results in the system getting released whenever a window is closed this would break the interpreter still being used by other windows.

I've tried setting the delegate in -init and the program crash's. This is nothing to do with the interpreter since it happens when I unplug it .

Maybe you could explain how you manage to set the delegate in -init while avoiding this? .

Maybe I could waggle something if objective C has class variables?

Thanks for your reply,

Mark.
__________________
12" G4 IBook (1GHz) named Darwin: 60GB HardDrive, BlueTooth, Airport Extreme coming soon?
netytan is offline   0 Reply With Quote
Old Mar 1, 2006, 03:32 PM   #4
robbieduncan
Moderator
 
robbieduncan's Avatar
 
Join Date: Jul 2002
Location: London
Does NSApp actually awakeFromNib? It's not normally serialised into a nib file so would not wake up. Have you actually checked that the awakeFromNib is called.

On the dealloc point I'm not sure that these are guaranteed to run on app shutdown, but I would have thought that they normally get called.
robbieduncan is offline   0 Reply With Quote
Old Mar 1, 2006, 03:46 PM   #5
netytan
Thread Starter
macrumors 6502
 
Join Date: May 2004
Quote:
Originally Posted by robbieduncan
Does NSApp actually awakeFromNib? It's not normally serialised into a nib file so would not wake up. Have you actually checked that the awakeFromNib is called.

On the dealloc point I'm not sure that these are guaranteed to run on app shutdown, but I would have thought that they normally get called.
Wow ok, I put a NSLog in awakeFromNib and it's a no go. Where is the delegate usually set. I put it in awakeFromNib because of an example I found on CocoaDevCentral and it crash's in other methods for some reason.

Edit: if it makes a difference this is a document based application.

Mark.
__________________
12" G4 IBook (1GHz) named Darwin: 60GB HardDrive, BlueTooth, Airport Extreme coming soon?
netytan is offline   0 Reply With Quote
Old Mar 1, 2006, 03:55 PM   #6
robbieduncan
Moderator
 
robbieduncan's Avatar
 
Join Date: Jul 2002
Location: London
Personally I do it in Interface Builder!

Open MainMenu.nib (or whatever your main nib is called). Drag the delegate header to the IB window. Create an instance of that object. Now connect the File's Owner to it (and select delegate).
robbieduncan is offline   0 Reply With Quote
Old Mar 1, 2006, 04:33 PM   #7
netytan
Thread Starter
macrumors 6502
 
Join Date: May 2004
Quote:
Originally Posted by robbieduncan
Personally I do it in Interface Builder!

Open MainMenu.nib (or whatever your main nib is called). Drag the delegate header to the IB window. Create an instance of that object. Now connect the File's Owner to it (and select delegate).
That doesn't quite work for document based applications beacause the files owner is already an instance of that type and has no deligate .

You also cant create an instance of NSApplication in order to link that way *sigh*, and it should be so simple.

Mark.
__________________
12" G4 IBook (1GHz) named Darwin: 60GB HardDrive, BlueTooth, Airport Extreme coming soon?
netytan is offline   0 Reply With Quote
Old Mar 1, 2006, 04:37 PM   #8
caveman_uk
Guest
 
caveman_uk's Avatar
 
Join Date: Feb 2003
Location: Hitchin, Herts, UK
Quote:
Originally Posted by robbieduncan
Does NSApp actually awakeFromNib? It's not normally serialised into a nib file so would not wake up. Have you actually checked that the awakeFromNib is called.
No, but a controller object does which is where I'd put it.

OP, your app controller is an NSObject subclass isn't it? You don't subclass NSApplication - well you can but I've never done it.

BTW, the way I set the NSApp delegate is [NSApp setDelegate:self]; as I usually set it in the init method of the app controller class that is to be the NSApp delegate.
caveman_uk is offline   0 Reply With Quote
Old Mar 1, 2006, 04:38 PM   #9
robbieduncan
Moderator
 
robbieduncan's Avatar
 
Join Date: Jul 2002
Location: London
Quote:
Originally Posted by netytan
That doesn't quite work for document based applications beacause the files owner is already an instance of that type and has no deligate .

You also cant create an instance of NSApplication in order to link that way *sigh*, and it should be so simple.

Mark.
It does work for document based apps. I do it this way in a document based app. The Files Owner in MainMenu.nib (NOT MyDocument.nib) is an NSApplication.
robbieduncan is offline   0 Reply With Quote
Old Mar 1, 2006, 04:42 PM   #10
robbieduncan
Moderator
 
robbieduncan's Avatar
 
Join Date: Jul 2002
Location: London
OK, I've put a bare example of a Cocoa Document app with a delegate object getting set in Interface Builder here.

Updated with applicationWillTerminate (I suppose it's a good idea to demonstrate that it works!)
robbieduncan is offline   0 Reply With Quote
Old Mar 1, 2006, 05:51 PM   #11
netytan
Thread Starter
macrumors 6502
 
Join Date: May 2004
Quote:
Originally Posted by robbieduncan
OK, I've put a bare example of a Cocoa Document app with a delegate object getting set in Interface Builder here.

Updated with applicationWillTerminate (I suppose it's a good idea to demonstrate that it works!)
Are you single because I could kiss you . Finally it works. One thing I am noticing though is that the contents of the -init are being run twice, is this because there is now an instance in the MainMenu.nib as-well as the one bound too the main document window?

Man, i'll never doubt you again . I got the opposite end of what you were saying there obviously.

In which case is there a way I might separate the two off, what I want to do is do a specific action when a window is opened. Before I was doing this in init but I'm sure theres another way, maybe in .

Thank you so much!

Mark.
__________________
12" G4 IBook (1GHz) named Darwin: 60GB HardDrive, BlueTooth, Airport Extreme coming soon?
netytan is offline   0 Reply With Quote
Old Mar 1, 2006, 06:01 PM   #12
robbieduncan
Moderator
 
robbieduncan's Avatar
 
Join Date: Jul 2002
Location: London
Quote:
Originally Posted by netytan
Are you single because I could kiss you . Finally it works. One thing I am noticing though is that the contents of the -init are being run twice, is this because there is now an instance in the MainMenu.nib as-well as the one bound too the main document window?

Man, i'll never doubt you again . I got the opposite end of what you were saying there obviously.

In which case is there a way I might separate the two off, what I want to do is do a specific action when a window is opened. Before I was doing this in init but I'm sure theres another way, maybe in .

Thank you so much!

Mark.
If you have an instance of the class in MainMenu and another in MyDocument each will be inited (and then awakeFromNibed). Every new document will cause another instance to be created as well. If this object is your application delegate it should only be in main Menu. If it has some sort of per-document functionality split that into another class and put that in the document nib.

Sorry to say I'm not much into kissing guys! Why do hot chicks never ask programming questions?
robbieduncan is offline   0 Reply With Quote
Old Mar 1, 2006, 06:12 PM   #13
netytan
Thread Starter
macrumors 6502
 
Join Date: May 2004
Quote:
Originally Posted by robbieduncan
If you have an instance of the class in MainMenu and another in MyDocument each will be inited (and then awakeFromNibed). Every new document will cause another instance to be created as well. If this object is your application delegate it should only be in main Menu. If it has some sort of per-document functionality split that into another class and put that in the document nib.

Sorry to say I'm not much into kissing guys! Why do hot chicks never ask programming questions?
Mmmm Well, I'm not sure.

I don't have anything in my init as of yet but I was going to use it to preform actions performing actions when the window opens.

I can see your point about splitting the classes up however I'm using the document class to start my interpreter because I need to used make function call into the interpreter in the document then again I will probably need to do it in both nibs.

Is MainMenu loaded first?

Maybe it is best to put it in the MainMenu Nib what do you think honestly? I know there are a lot of questions but I like to do things in the best way I can.

LOL I'm not bothered about kissing boys though girls are better. It was an expression not a threat don't worry .

Thanks a lot for all your help,

Mark.
__________________
12" G4 IBook (1GHz) named Darwin: 60GB HardDrive, BlueTooth, Airport Extreme coming soon?
netytan is offline   0 Reply With Quote
Old Mar 1, 2006, 06:21 PM   #14
robbieduncan
Moderator
 
robbieduncan's Avatar
 
Join Date: Jul 2002
Location: London
MainMenu should be loaded first (and only be loaded once). I'd use that for an app delegate which can respond to applicationWillTerminate.

If you need to start your interpreter per document then put the code to start it in the document class.

You can then use the applicationWillTerminate in the app delegate to loop over all documents (get a list from NSDocumentController) and call a method in the document class to stop the interpreter.
robbieduncan is offline   0 Reply With Quote
Old Mar 1, 2006, 08:27 PM   #15
netytan
Thread Starter
macrumors 6502
 
Join Date: May 2004
Quote:
Originally Posted by robbieduncan
MainMenu should be loaded first (and only be loaded once). I'd use that for an app delegate which can respond to applicationWillTerminate.

If you need to start your interpreter per document then put the code to start it in the document class.

You can then use the applicationWillTerminate in the app delegate to loop over all documents (get a list from NSDocumentController) and call a method in the document class to stop the interpreter.
Thanks Robbie,

it took about 5 minutes and it works perfectly. I can now do something when the Apps loaded and do something when the windows load.

I'm currently initializing the interpreter in the initialize method because it only gets called once in the lifetime of the class. Would you say thats a good idea or not? It's not doing any harm so I'm tempted to just leave it and be 100%.

If the interpeter starts more than once then things could get very unstable because the interpreter doesn't return instances of itself it runs in the global scope, hence all the fuss about loading it at the beginning and closing it down at the very end .

It occurs to me that I could now move the initialization to init. Would you recommend this?

Thanks a lot,

Mark.
__________________
12" G4 IBook (1GHz) named Darwin: 60GB HardDrive, BlueTooth, Airport Extreme coming soon?
netytan is offline   0 Reply With Quote
Old Mar 2, 2006, 07:05 AM   #16
robbieduncan
Moderator
 
robbieduncan's Avatar
 
Join Date: Jul 2002
Location: London
This is getting a bit confusing!

My understanding of what you are saying is this: you are writing a Cocoa document based app. You are using some sort of C based interpreter. You want to have a single instance of the interpreter shared amongst all documents? Thus you need to have an interpreter instance created at the start of the app and shutdown at the end.

So what I would do would be create a Cocoa wrapper for the interpreter that is a singleton object (this is reasonably easy). If the interpreter needs to be shutdown cleanly have a shutdown method in the wrapper can call it from the app delegate when the app is shutting down. If you want to initialise the interpreter when the app starts do it in the app delegate. Otherwise when the first document is created it will create the instance.

So you will have something like:

@interface InterpreterWrapper

+(InterpreterWrapper*) sharedInstance; // Whenever you want to get an instance of this class use this.
- (void) doInterpreterStuff; // Possibly more than one of these: do the interpreter stuff
- (void) shutdownInterpreter; // Call when the app is shutting down.

@end

Your implementation should look something like this

@implementation InterpreterWrapper

static InterpreterWrapper *wrapperSharedInstance;

+(InterpreterWrapper*) sharedInstance
{
if (wrapperSharedInstance==nil)
{
wrapperSharedInstance = [[InterpreterWrapper alloc] init];
}
return wrapperSharedInstance;
}

@end

For more details (including protecting init so as you can't break the patern) see this cocoadev page.
robbieduncan is offline   0 Reply With Quote
Old Mar 2, 2006, 12:11 PM   #17
netytan
Thread Starter
macrumors 6502
 
Join Date: May 2004
Actually the singleton class was the first thing I did and that works fine, what I wasn't sure about was weather or not to move it from the -initialize or -init in classed that use it .

And then of course there was also the issue of not being able to shut the interpreter down but all good now.

I've decided to leave it where it is anyhow because it's being bound to a class method so it makes sense and adds that much extra security.

Thanks for all your help Robbie,

Mark.
__________________
12" G4 IBook (1GHz) named Darwin: 60GB HardDrive, BlueTooth, Airport Extreme coming soon?
netytan is offline   0 Reply With Quote

Reply
MacRumors Forums > Apple Systems and Services > Programming > Mac Programming

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Similar Threads
thread Thread Starter Forum Replies Last Post
applicationWillTerminate not being called Dreamspinner Mac Programming 10 Jan 1, 2013 09:34 AM

Forum Jump

All times are GMT -5. The time now is 05:20 AM.

Mac Rumors | Mac | iPhone | iPhone Game Reviews | iPhone Apps

Mobile Version | Fixed | Fluid | Fluid HD
Copyright 2002-2013, MacRumors.com, LLC