Cocoa: я получил информацию от пользователя. Что теперь?

В двух словах моя программа делает следующее: она выполняется и периодически принимает пользовательский ввод с помощью 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];» чего не происходит. Пожалуйста, может кто-нибудь предложить способ решения этой ситуации.

ИЗМЕНИТЬ:

Спасибо Боб за ответ. Теперь я понял, в чем была моя ошибка. Итак, я попробовал метод уведомления, используя цикл while, как показано:

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

в середине моей программы, чтобы дождаться прихода уведомления и установить для переменной bool значение true. Но теперь проблема в том, что он переходит в бесконечный цикл, и мое приложение зависает.

нет ничего похожего на эквивалент MFC, где он напрямую ожидает ввода пользователя. Неужели так сложно создать окно и получить пользовательский ввод, или я действительно что-то упускаю????


person King    schedule 26.08.2009    source источник
comment
Вы уже задавали этот вопрос на stackoverflow.com/questions/1337591/ . Пожалуйста, старайтесь не публиковать каждый раз новый вопрос; используйте существующий поток, когда это возможно.   -  person Shaggy Frog    schedule 27.08.2009


Ответы (1)


Ваша проблема в том, что «-[NSWindowController showWindow:]» не блокирует ожидание ввода окна. Вы вызываете это, что говорит вашему приложению показать окно, но затем оно немедленно выполняет следующую строку, устанавливая пароль равным nil, так как он еще не установлен.

IBAction происходит во время цикла выполнения. По сути, поток вашего приложения:

Инициализировать App Controller -> показать окно -> установить пароль на nil -> запустить цикл выполнения несколько раз, ожидая ввода -> нажать кнопку «ОК» -> установить поле пароля контроллера -> вернуться к циклу выполнения.

Вы должны прочитать о циклах выполнения, чтобы попытаться понять, что именно здесь происходит. Приведенная выше ссылка научит вас тому, что вам нужно узнать, и многому другому. Он не многопоточный, но работает не в том порядке, в котором вы ожидаете. По сути, вам нужно изменить его так, чтобы в myController.mm вы ждали ввода. Это можно сделать с помощью Уведомлений или просто вызов метода в IBAction, который сообщает контроллеру, что пароль изменился (что, по сути, и делает уведомление).

Редактировать: на самом деле, как только вы это исправите, вы должны быть уверены, что вызываете «сохранение» для пароля, который вы получаете во время IBAction, иначе вы выйдете из строя, как только эта строка будет автоматически освобождена, и вы попытаетесь получить к ней доступ. Руководство по управлению памятью

person bobDevil    schedule 26.08.2009