可可:我得到了用户的意见 - 现在是什么?

时间:2009-08-26 22:38:48

标签: cocoa events event-handling nswindow

简而言之,我的程序所做的是:它使用nswindow(由我的NSWindowController对象控制)执行并定期接受用户输入并继续执行。

这是myController.mm,它调用并显示用于输入用户输入的窗口:

EncryptPasswordDlgController encPassController = [[EncryptPasswordDlgController alloc] init];

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

这是我的nswindowcontroller对象代码:

#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
单击确定或取消按钮后,相应的IBAction方法被调用并按要求执行,即显示从文本字段获取用户输入的窗口,然后单击确定它也更新密码。但是在完成IBAction clickOK方法的执行之后,它应该返回myController.mm并通过执行下一个语句“NSString * inputPassword = [encPassController password];”来检索密码。这没有发生。请一个人建议一种解决这种情况的方法。

修改

感谢Bob的回复。 我现在明白了我的错误。 所以我通过使用while循环尝试了通知方法,如下所示:

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

在我的程序中间,以便等到通知到来并将bool变量设置为true。 但现在的问题是,它将进入无限循环,我的应用程序陷入困境。

没有像MFC等效的东西,它直接等待用户输入。 真的很难创建一个窗口并获得用户输入,或者我真的错过了这里的东西????

1 个答案:

答案 0 :(得分:1)

你的问题是' - [NSWindowController showWindow:]'不会阻止等待窗口输入。你调用它,告诉你的应用程序显示窗口,然后它立即执行下一行,将密码设置为nil,因为它尚未设置。

IBAction发生在Run Loop期间。基本上,您的应用程序的流程是:

初始化App Controller - >显示窗口 - >将密码设置为nil - >运行Run Loop多次等待输入 - >按下确定按钮 - >设置控制器密码字段 - >回到跑步循环。

您应该阅读run loop以尝试了解这里到底发生了什么。以上链接将教您如何学习,以及更多。它不是多线程的,但它没有按照您期望的顺序运行。基本上,您需要重新排列它,以便在myController.mm中等待输入。这可以通过Notifications来完成,或者只是通过调用IBAction中的方法来告诉控制器密码已经改变(这基本上是通知所做的)。

编辑:实际上,一旦你解决了这个问题,你应该确保在IBAction期间给你的密码调用'retain',否则一旦该字符串被自动释放并且你试图访问它就会崩溃。 Memory Management Guide