2009-08-26 3 views
0

En bref, ce que mon programme fait est: il exécute et prend l'entrée de l'utilisateur périodiquement en utilisant nswindow (qui est contrôlé par mon objet NSWindowController) et continue l'exécution.Cocoa: J'ai l'entrée de mon utilisateur - Maintenant quoi?

ici est mon myController.mm qui appelle et montrant la fenêtre pour prendre l'entrée d'utilisateur:

EncryptPasswordDlgController encPassController = [[EncryptPasswordDlgController alloc] init]; 

[encPassController showWindow:self]; 
NSString *inputPassword = [encPassController password]; 

ici est mon NSWindowController code objet:

#import "EncryptPasswordDlgController.h" 

@implementation EncryptPasswordDlgController 
-(id) init 
{ 
    return self; 
} 

- (IBAction)showWindow:(id)sender 
{ 
    [super showWindow:sender]; 
    encryptPasswordDlgWindowController = [[NSWindowController alloc] initWithWindowNibName:@"EncryptionPasswordDlg"]; 
    [encryptPasswordDlgWindowController loadWindow]; 
    [[self window] makeKeyAndOrderFront:[self window]]; 

    return; 
} 

-(IBAction)clickOK:(id) sender 
{ 
    password = [passwordField stringValue]; 

    NSLog(@"password is %@", password); 


    [[self window] close]; 
    return; 
} 

-(NSString *)password 
{ 
    return password; 
} 

-(IBAction)clickCancel:(id) sender 
{ 
// close the window 
    password = nil; 
    [[self window] close]; 
    //return; 
} 
@end 

Après avoir cliqué sur le bouton OK ou annuler bouton, la méthode IBAction respective est appelée et est exécutée comme requis, c'est-à-dire qu'elle affiche la fenêtre prenant l'entrée de l'utilisateur à partir du champ de texte et en cliquant sur ok elle met également le mot de passe à jour. Mais après avoir terminé l'exécution de la méthode clickAc IBAction, il devrait retourner à myController.mm et récupérer le mot de passe en exécutant l'instruction suivante "NSString * inputPassword = [mot de passe encPassController];" ce qui ne se passe pas. S'il vous plaît, quelqu'un peut-il suggérer un moyen de s'attaquer à cette situation?

EDIT:

Merci Bob pour la réponse. J'ai maintenant compris ce que mon erreur était. donc j'ai essayé la méthode de notification en utilisant une boucle while comme le montre:

while(isPasswordReceivedForEncryption == NO) 
{ 
      sleep(10000); 
      //continue; 
} 

au milieu de mon programme afin d'attendre la notification arrive et définit la variable bool true. Mais maintenant, le problème est qu'il va en boucle infinie et mon application est coincé.

Y at-il rien de tel que l'équivalent MFC où il attend directement l'entrée de l'utilisateur. Vraiment, est-ce si difficile de créer une fenêtre et d'obtenir des commentaires de la part de l'utilisateur ou est-ce qu'il me manque vraiment quelque chose ici?

+0

Vous avez déjà posé cette question à http://stackoverflow.com/questions/1337591/nswindowcontroller-program-execution.Essayez d'éviter de poster une nouvelle question à chaque fois. utilisez votre fil existant autant que possible. –

Répondre

1

Votre problème est que '- [NSWindowController showWindow:]' ne bloque pas l'attente de l'entrée de la fenêtre. Vous appelez cela, qui indique à votre application d'afficher la fenêtre, mais ensuite il exécute immédiatement la ligne suivante, en définissant le mot de passe à zéro, car il n'a pas encore été défini.

L'IBAction se produit pendant un Run Loop. Fondamentalement, le flux de votre application est:

Initialiser App Controller -> afficher la fenêtre -> définir le mot de passe à zéro -> exécuter la boucle d'exécution un certain nombre de fois en attente d'entrée -> bouton Ok enfoncé -> définir la champ mot de passe du contrôleur -> revenir à la boucle d'exécution.

Vous devriez lire les boucles d'exécution pour essayer de comprendre ce qui se passe exactement ici. Le lien ci-dessus vous apprendra ce que vous devez apprendre, et bien plus encore. Ce n'est pas multithread, mais il ne fonctionne pas dans l'ordre attendu. Fondamentalement, vous devez le réorganiser de telle sorte que dans myController.mm, vous attendez l'entrée. Cela peut être fait via Notifications, ou simplement en appelant une méthode dans l'IBAction qui indique au contrôleur que le mot de passe a changé (ce qui est essentiellement ce que fait la notification). Edit: En fait, une fois que vous avez résolu ce problème, vous devez être sûr que vous appelez 'retain' sur le mot de passe que vous obtenez pendant l'IBAction, sinon vous allez vous écraser une fois que cette chaîne sera auto-libérée et que vous essayerez d'y accéder. Memory Management Guide

Questions connexes