2009-06-25 4 views
1

Я работаю через Beginning iPhone Development. В книге указан этот метод:Поток управления в Objective-C

-(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 = @""; 
} 

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

ответ

3

Да, и поток делает Возврат к методу спина. Фокус в том, в вызове которое выполняет метод playWinSound:

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

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

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

0

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

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

Этот метод останавливает действие, возвращается сразу и сбрасывает текст на "". Если он действительно ждал, а затем вызвал селектор после таймаута, он потерял бы ресурсы.

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

Apple reference:

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

Смежные вопросы