0

簡単に言うと、私のプログラムは、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

[OK]または[キャンセル]ボタンをクリックすると、それぞれのIBActionメソッドが呼び出され、必要に応じて実行されます。つまり、テキストフィールドからユーザー入力を取得するウィンドウが表示され、[OK]をクリックするとパスワードも更新されます。ただし、IBAction clickOKメソッドの実行が終了したら、myController.mmに戻り、次のステートメント「NSString * inputPassword =[encPassControllerpassword];」を実行してパスワードを取得する必要があります。それは起こっていません。この状況に取り組む方法を誰かが提案できますか。

編集:

返信してくれたボブに感謝します。私は今、自分の間違いが何であるかを理解しました。そこで、次のようにwhileループを使用して通知方法を試しました。

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

プログラムの途中で、通知が届くまで待機し、bool変数をtrueに設定します。しかし、今の問題は、それが無限ループに入り、私のアプリケーションがスタックしていることです。

ユーザー入力を直接待機するMFCに相当するものはありません。ウィンドウを作成してユーザー入力を取得するのは本当に難しいですか、それともここで何かが本当に足りないのですか????

4

1 に答える 1

1

問題は、'-[NSWindowController showWindow:]'がウィンドウ入力の待機をブロックしないことです。これを呼び出すと、アプリにウィンドウを表示するように指示されますが、パスワードがまだ設定されていないため、すぐに次の行が実行され、パスワードがnilに設定されます。

IBActionは、実行ループ中に発生します。基本的に、アプリのフローは次のとおりです。

AppControllerの初期化->ウィンドウの表示->パスワードをnilに設定->実行ループを実行して入力を待機->[OK]ボタンが押された->コントローラーのパスワードフィールドを設定->実行ループに戻る

ここで何が起こっているのかを正確に理解するために、実行ループをよく読んでください。上記のリンクは、あなたが学ぶ必要があることなどを教えてくれます。マルチスレッドではありませんが、期待した順序で実行されていません。基本的に、myController.mmで入力を待つように再配置する必要があります。これは、通知を介して、またはパスワードが変更されたことをコントローラーに通知するIBActionのメソッドを呼び出すことによって実行できます(これは基本的に通知が行うことです)。

編集:実際、これを修正したら、IBAction中に取得したパスワードで「retain」を呼び出すようにしてください。そうしないと、その文字列が自動解放されてアクセスしようとするとクラッシュします。メモリ管理ガイド

于 2009-08-26T22:52:28.587 に答える