Как обработать методы класса, вызываемые снова до их завершения? - PullRequest
1 голос
/ 03 сентября 2010

Как лучше всего справиться с этой ситуацией на устройстве iPhone: моя программа изменяет высоту звука между двумя значениями. Нажатие кнопки вызывает метод с циклом while, который выполняет линейное изменение с небольшими приращениями. Это займет некоторое время, чтобы закончить. Тем временем пользователь нажал другую кнопку, вызвав тот же метод. Теперь я хочу, чтобы цикл в первом вызове был остановлен, а во втором - начался с текущего состояния. Вот как должен выглядеть метод:

-(void)changePitchSample: (float) newPitch{
float oldPitch=channel.pitch;
if (oldPitch>newPitch) {
    while (channel.pitch>newPitch) {
        channel.pitch = channel.pitch-0.001;
    }
}
else if (oldPitch<newPitch) {
    while (channel.pitch<newPitch) {
        channel.pitch = channel.pitch+0.001;
    }
}

}

Теперь, как лучше всего справиться с ситуацией, когда метод вызывается снова? Нужна ли мне какая-то многопоточность? Мне не нужны два процесса, идущие одновременно, поэтому, похоже, должно быть какое-то более простое решение, которое я не могу найти (будучи новичком в этом языке).

Любая помощь с благодарностью!

Ответы [ 3 ]

1 голос
/ 03 сентября 2010

Не используйте цикл while;это блокирует все остальное.Используйте таймер и конечный автомат.Таймер может вызывать конечный автомат со скоростью, с которой вы хотите, чтобы все изменилось.Конечный автомат может посмотреть на последнее значение линейного изменения и время последнего нажатия кнопки (или даже на массив времени событий пользовательского интерфейса) и решить, следует ли и в какой степени увеличивать громкость в течение следующего временного шага (логика часто является просто кучейиз операторов if и select / case, если алгоритм управления не поддается красивой таблице).Затем конечный автомат может вызвать объект или процедуру, которая обрабатывает фактический уровень звука.

1 голос
/ 03 сентября 2010

Посмотрите NSOperation и Руководство по программированию параллелизма . Вы можете сначала начать операцию увеличения высоты тона, а также сохранить объект операции. При втором вызове вы можете позвонить [operation cancel], чтобы остановить последнюю операцию. Начните вторую операцию, чтобы уменьшить высоту тона, а также сохранить новый объект.

Кстати: то, что вы делаете сейчас, очень плохо, так как вы «блокируете основной поток». Расчеты, которые занимают некоторое время, не должны выполняться напрямую. Возможно, вам также стоит взглянуть на NSTimer, чтобы сделать ваш код независимым от скорости процессора.

1 голос
/ 03 сентября 2010

Вы не можете так делать. Пока ваш цикл работает, никакие события не будут обработаны. Поэтому, если пользователь нажимает кнопку еще раз, ничего не произойдет до завершения цикла. Также, как это вы не можете контролировать скорость своей рампы. Я бы предложил использовать NSTimer. В вашем методе changePitchSample: вы сохраняете новую высоту (не перезаписываете старую) и запускаете таймер, который срабатывает один раз. Когда таймер срабатывает, вы увеличиваете свою высоту, и если она меньше новой высоты, вы перезапускаете таймер.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...