Контроль потока в Objective-C - PullRequest
1 голос
/ 26 июня 2009

Я работаю через Начало разработки iPhone . В книге этот метод:

-(void)playWinSound
{
    NSString *path = [[NSBundle mainBundle] pathForResource:@"win" ofType:@"wav"];
    SystemSoundID soundID;
    AudioServicesCreateSystemSoundID((CFURLRef)[NSURL fileURLWithPath:path], &soundID);
    AudioServicesPlaySystemSound (soundID);     
    winLabel.text = @"WIN!";
    [self performSelector:@selector(showButton) withObject:nil afterDelay:1.5];
}

-(IBAction)spin{
    BOOL win = NO;
    int numInRow = 1;
    int lastVal = -1;
    for (int i = 0; i < 5; i++)
    {
        int newValue = random() % [self.column1 count];

        if (newValue == lastVal)
            numInRow++;
        else
            numInRow = 1;

        lastVal = newValue;
        [picker selectRow:newValue inComponent:i animated:YES];
        [picker reloadComponent:i];
        if (numInRow >= 3)
            win = YES;
    }

    button.hidden = YES;
    NSString *path = [[NSBundle mainBundle] pathForResource:@"crunch" ofType:@"wav"];
    SystemSoundID soundID;
    AudioServicesCreateSystemSoundID((CFURLRef)[NSURL fileURLWithPath:path], &soundID);
    AudioServicesPlaySystemSound (soundID);

    if (win)
        [self performSelector:@selector(playWinSound) withObject:nil afterDelay:.5];
    else
        [self performSelector:@selector(showButton) withObject:nil afterDelay:.5];

    winLabel.text = @"";
}

Когда вы нажимаете кнопку прокрутки, вызывается этот метод прокрутки. Если выигрыш ДА, вызывается playWinSound, который изменяет значение winLabel на @ "Win!". Почему, если вращение приводит к победе, текст в winLabel изменится на @ "Win!" и остается таким. Разве поток не должен вернуться к методу вращения, который изменит winLabel на @ ""?

Ответы [ 3 ]

3 голосов
/ 26 июня 2009

Да, и поток делает возврат к методу вращения. Хитрость заключается в вызове, который выполняет метод playWinSound:

[self performSelector:@selector(playWinSound) withObject:nil afterDelay:.5];

Обратите внимание на часть метода afterDelay . Это запланирует вызов playWinSound в первое доступное время по истечении 0,5 секунд. В частности, вызов будет происходить в начале первого цикла выполнения через 0,5 секунды. Этот метод вызывается внутри уже запущенного цикла выполнения, поэтому playWinSound не может быть выполнен до тех пор, пока не будет возвращен метод spin.

Тем не менее, это кажется очень странным способом структурировать программу. Я предполагаю, что они устанавливают winLabel.text на @"", чтобы убедиться, что он возвращается к пустой строке, если только он не станет @"Win!", но я бы структурировал его совсем по-другому. Тем не менее, именно поэтому он работает.

1 голос
/ 26 июня 2009
[self performSelector:@selector(playWinSound) withObject:nil afterDelay:.5];

Этот метод ставит в очередь действие, сразу же возвращает его и сбрасывает текст в «». Если бы он действительно ждал, а затем вызвал селектор после истечения времени ожидания, это потратило бы впустую ресурсы.

Действие выполняется после тайм-аута и устанавливает текст «WIN».

Apple, ссылка :

Этот метод устанавливает таймер для выполнения сообщение aSelector на текущий цикл выполнения потока ...

0 голосов
/ 26 июня 2009

Я думаю, что происходит то, что при вызове метода executeSelector получается период afterDelay ... поэтому метод ставится в очередь, выполняется код winLabel.text = @ "", а затем метод playWinSound срабатывает, изменяя снова этикетка.

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