Cocoa-UI: отложенный выбор параметров…. отложенный

#multithreading #macos #cocoa #selector #delay

#многопоточность #macos #cocoa #селектор #задержка

Вопрос:

Контекст :

В моем приложении для Mac, когда я нажимаю на элемент списка, объекту, который что-то делает в фоновом режиме, отправляется уведомление, в то время как в пользовательском интерфейсе есть ожидающее сообщение. Все это происходит в окне, из которого вы можете выйти с помощью кнопки «Закрыть». Кнопка по умолчанию отключена при отправке уведомления.

Что я хочу сделать, так это функцию тайм-аута, которая позволяет пользователю выйти из этой Windows через пару минут, следовательно, активируя кнопку закрытия.

Код :

 - (IBAction)onChangeOperator:(id)sender
{
    [self performSelector:@selector(timerFired:) withObject:nil afterDelay:2.0];
    ....
    ....
    //takes time
    ....
}

-(void) timerFired:(NSTimer *) theTimer {
[close_button setEnabled:YES];
}
  

Проблема :
Кнопка не включена до завершения onChangeOperator, тогда как я хочу, чтобы она была включена, как только будет запущен селектор.

Я думаю, что это поточная штука, но я не могу понять.

Комментарии:

1. Просто для ясности, вы хотите, чтобы кнопка была включена через 2 секунды, но на самом деле она не включается до onChangeOperator завершения?

Ответ №1:

Из документации, performSelector:withObject:afterDelay:

После задержки вызывает метод получателя в текущем потоке, используя режим по умолчанию.

Таким образом, текущий поток все еще заблокирован. Вместо этого вы должны запустить свою дорогостоящую операцию в onChangeOperator в новом потоке:

 - (IBAction)onChangeOperator:(id)sender 
{     
    [self performSelector:@selector(timerFired:) withObject:nil afterDelay:2.0];
    [self performSelectorInBackground:@selector(doUpdates) withObject:nil];
}

-(void) timerFired:(NSTimer *) theTimer 
{ 
    [close_button setEnabled:YES]; 
} 

-(void)doUpdates
{
    .... stuff that takes time....
}
  

Комментарии:

1. Это то, что я нашел и попробовал, но это не работает. Не удается выполнить мою операцию, все мое приложение является монотонным, поэтому происходит сбой doUpdates. В любом случае, спасибо, я найду другой способ или исправлю этот недостаток дизайна.

2. Возможно, стоит задать новый вопрос, чтобы выяснить, почему вы не можете выполнять другие свои действия в фоновом потоке.