Hi, I'm a newbie in Mac Dev. I come from iPhone dev. My question relates to non-modal windows management. It's quite different from the iPhone and it's memory management model.
Say for example, i have a preference window, i can use something like that to show the window:
-(IBAction)showPreferenceController:(id)sender {
if (!preferenceController) {
preferenceController = [[PreferenceController alloc]init];
}
[preferenceController showWindow:preferenceController];
}
But with this code, the window will stay in memory during app life because the window is never released.
To avoid that, I could also use the method described here :
stackoverflow.com/questions/1391260/who-owns-an-nswindowcontroller-in-standard-practice
Create in PreferenceController
a + (id) sharedInstance
and release the window using (void)windowWillClose:(NSNotification *)notification
I see many cocoa code samples where non-modal windows are never released.
For example here : http://www.mattballdesign.com/blog/2008/10/01/building-a-preferences-window/ : The preference panel and all the subviews are created in awakeFromNib
and so will live in memory during all app life.
If you take for example Xcode app, there are a lot of non-modal windows :
- Global Find window (CMD+MAJ+F)
- App Info Panel
- Help Window
- ...
I suppose that these windows are released when they are closed to keep memory as low as possible. I would like some advices to know the best way to manage non-modal windows in a cocoa app. Keep in memory? Releasing asap? I know a mac has a lot of memory compared to an iPhone but I also think it's not good to keep in memory objects we are not using.
Thanks.
Edited with Rob post :
I send -autorelease to the window and set my pointer to nil so I'll recreate the window later. This is similar to the technique you cite, though whether or not to use +sharedController for the Controller isn't related; you can do this whether you have a shared controller or not.
I don't how to do that without a singleton (+sharedController).
I explain what I mean with this example:
In the app Controller :
@interface AppController : NSObject <NSApplicationDelegate> {
Implementation :
-(IBAction)showPreferenceController:(id)sender {
if (!preferenceController) {
preferenceController = [[PreferenceController alloc]init];
}
[preferenceController showWindow:preferenceController];
}
In the preferences controller :
@interface PreferenceController : NSWindowController <NSWindowDelegate>
Implementation :
- (void)windowWillClose:(NSNotification *)notification {
[self autorelease];self=nil;
}
It will crash when i close and reopen after the window : preferenceController is released but not equal to nil. So I need to set preferenceController to nil when the window is closed.
There is no problem to do that with a singleton.
Without singleton, I should set appController as the delegate of Preference Window to be able to set preferenceController to nil when the window is closed. But i don't like that way.
Edited with Preston comments
I didn't say it but I want only one instance of my non-modal window even if we call -(IBAction)showPreferenceController:(id)sender
several times.
That's why I test if preferenceController is equal to nil or not in appController.
So, I need to set preferenceController to nil in appController if we close the window.
So the solution would be :
In AppController, listening NSWindowWillCloseNotification:
- (void)windowWillClose:(NSNotification *)notification {
if ([notification object] == [preferenceController window]) {
[preferenceController autorelease];
preferenceController = nil;
}
}
Is it correct? Is this the only one solution? because it seems a little bit complicated just to manage my non modal window...