问题
In a nutshell what my program does is: it executes and takes user input periodically using nswindow (which is controlled by my NSWindowController object) and continues execution.
here is my myController.mm which is calling and showing the window to take user input:
EncryptPasswordDlgController encPassController = [[EncryptPasswordDlgController alloc] init];
[encPassController showWindow:self];
NSString *inputPassword = [encPassController password];
here is my nswindowcontroller object code:
#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
after i click the ok or cancel button, the respective IBAction method is getting called and is getting executed as required i.e it is showing the window taking user input from text field and on clicking ok it is updating the password also. But after it finishes execution of IBAction clickOK method, it should return back to myController.mm and retrieve the password by executing the next statement "NSString *inputPassword = [encPassController password];" which is not happening. Please can anone suggest a way to tackle this situation.
EDIT:
Thanks Bob for the reply. I now understood what my mistake was. So i tried the notification method by using a while loop as shown:
while(isPasswordReceivedForEncryption == NO)
{
sleep(10000);
//continue;
}
in the middle of my program so as to wait till the notification comes and sets the bool variable to true. But now the problem is that it is going into infinite loop and my applicaton is getting stuck.
is there nothing like the MFC equivalent where it directly waits for user input. Really is it that difficult to create a window and get user input or am i really missing something over here????
回答1:
Your problem is that '-[NSWindowController showWindow:]' does not block waiting for window input. You call this, which tells your app to show the window, but then it immediately executes the next line, setting the password to nil, since it hasn't been set yet.
The IBAction occurs during a Run Loop. Basically, the flow of your app is:
Initialize App Controller -> show the window -> set password to nil -> run the Run Loop a bunch of times waiting for input -> Ok button gets pressed -> set the controllers password field -> go back to the run loop.
You should read up on run loops to try to understand what exactly is happening here. The above link will teach you what you need to learn, and much more. It's not multithreaded, but it is not running in the order you expect. Basically, you need to rearrange it such that in myController.mm, you wait for the input. This could be done via Notifications, or just by calling a method in the IBAction that tells the controller the password has changed (which is essentially what the Notification does).
Edit: Actually, once you fix this, you should be sure that you call 'retain' on the password you get during the IBAction, otherwise you will crash once that string gets autoreleased and you try to access it. Memory Management Guide
来源:https://stackoverflow.com/questions/1337930/cocoa-ive-got-my-users-input-now-what