Je suis un débutant dans Mac Dev. Je viens de l'iPhone dev. Ma question concerne la gestion des fenêtres non modales. C'est assez différent de l'iPhone et de son modèle de gestion de la mémoire.Gestion de la mémoire Windows non modale
Dites par exemple, j'ai une fenêtre de préférence, je peux utiliser quelque chose comme ça pour afficher la fenêtre:
-(IBAction)showPreferenceController:(id)sender {
if (!preferenceController) {
preferenceController = [[PreferenceController alloc]init];
}
[preferenceController showWindow:preferenceController];
}
Mais avec ce code, la fenêtre restera dans la mémoire pendant la vie de l'application, car la fenêtre est jamais libéré.
Pour éviter cela, je pourrais aussi utiliser la méthode décrite ici:
stackoverflow.com/questions/1391260/who-owns-an-nswindowcontroller-in-standard-practice
Créer dans PreferenceController
un + (id) sharedInstance
et libérer le fenêtre en utilisant (void)windowWillClose:(NSNotification *)notification
Je vois beaucoup d'échantillons de code de cacao où les fenêtres non-modales ne sont jamais libérées. Par exemple ici: http://www.mattballdesign.com/blog/2008/10/01/building-a-preferences-window/: Le panneau de préférences et toutes les sous-vues sont créés en awakeFromNib
et seront donc en mémoire pendant toute la vie de l'application.
Si vous prenez par exemple l'application Xcode, il y a beaucoup de fenêtres non modales:
- fenêtre Recherche globale (CMD + MAJ + F)
- Panel App Info
- Aide Fenêtre
-.
Je suppose que ces fenêtres sont libérées lorsqu'elles sont fermées pour maintenir la mémoire aussi faible que possible. Je voudrais quelques conseils pour connaître la meilleure façon de gérer les fenêtres non-modales dans une application de cacao. Garder en mémoire? Libérer dès que possible? Je sais qu'un mac a beaucoup de mémoire par rapport à un iPhone mais je pense aussi qu'il n'est pas bon de garder des objets mémoire que nous n'utilisons pas.
Merci.
édité avec Rob après:
J'envoyer -autorelease à la fenêtre et mettez mon pointeur à zéro alors je recréerai la fenêtre plus tard. Ceci est similaire à la technique que vous citez, bien que l'utilisation de + sharedController pour le contrôleur ne soit pas liée; vous pouvez le faire si vous avez un contrôleur partagé ou non.
Je ne sais pas comment faire cela sans singleton (+ sharedController).
j'expliquer ce que je veux dire avec cet exemple:
Dans l'application Controller:
@interface AppController : NSObject <NSApplicationDelegate> {
Mise en œuvre:
-(IBAction)showPreferenceController:(id)sender {
if (!preferenceController) {
preferenceController = [[PreferenceController alloc]init];
}
[preferenceController showWindow:preferenceController];
}
Dans le contrôleur de préférences:
@interface PreferenceController : NSWindowController <NSWindowDelegate>
Mise en œuvre:
- (void)windowWillClose:(NSNotification *)notification {
[self autorelease];self=nil;
}
Il se bloque lorsque je ferme et rouvre après la fenêtre: preferenceController est libéré mais pas égal à zéro. J'ai donc besoin de mettre à zeroController quand la fenêtre est fermée. Il n'y a aucun problème à le faire avec un singleton.
Sans singleton, je devrais définir appController en tant que délégué de la fenêtre de préférences pour être en mesure de définir le paramètre PreferController à zéro lorsque la fenêtre est fermée. Mais je n'aime pas ça.
Edité avec Preston commente
Je ne dis pas, mais je ne veux qu'une seule instance de ma fenêtre non modale même si nous appelons -(IBAction)showPreferenceController:(id)sender
plusieurs fois.
C'est pourquoi je teste si preferenceController est nul ou pas dans appController.
Donc, j'ai besoin de mettre à zéro dans le programme appController si vous fermez la fenêtre.
Donc, la solution serait:
En AppController, écoute NSWindowWillCloseNotification:
- (void)windowWillClose:(NSNotification *)notification {
if ([notification object] == [preferenceController window]) {
[preferenceController autorelease];
preferenceController = nil;
}
}
est-il exact? Est-ce la seule solution? parce que cela semble un peu compliqué de gérer ma fenêtre non modale ...
Vous ne devriez pas vous libérer ici (vous ne devriez presque jamais appeler [self release]). Vous devriez libérer self.window et régler self.window = nil. –
Aussi, je recommanderais ceci étant [self.window autorelease]; self.window = nil; ' De cette façon, la fenêtre peut finir de se fermer avant d'être libérée. –
Merci Rob, mon exemple était juste pour expliquer le problème car comme dit, l'exemple va planter. Je veux mettre PreferController à zéro et cela doit être implémenté dans appController. J'ai édité ma question avec vos derniers commentaires. – Benoit