2009-06-25 8 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 = @""; 
} 

스핀 단추를 클릭하면이 스핀 방식이 호출됩니다. win이 YES이면 winLabel의 값을 @ "Win!"으로 변경하는 playWinSound가 호출됩니다. 스핀 결과가 승리하면 winLabel의 텍스트가 @ "Win!"으로 변경됩니다. 그런 식으로 남는다. 흐름이 winLabel을 @ ""로 바꿀 스핀 방식으로 돌아 가지 않아야합니까?

답변

3

예, 흐름 으로 돌아갑니다.

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

참고있어서의 afterDelay 부 : 트릭은 playWinSound 방법을 수행하는 호이다. 이것은 0.5 초가 지난 후 첫 번째 가용 시간에 playWinSound의 호출을 스케줄합니다. 특히, 호출은 0.5 초가 지난 후 첫 번째 실행 루프의 시작 부분에서 발생합니다. 이 메서드는 이미 실행중인 루프에서 호출되므로 playWinSoundspin 메서드가 반환 될 때까지는 실행될 수 없습니다.

이것은 말하기를, 이것은 프로그램을 구성하는 매우 이상한 방법으로 보입니다. 나는 그것들이 winLabel.text@""으로 설정한다고 가정하고, 특별히 @"Win!"이 될 때까지는 그것이 빈 문자열로 다시 리셋되는 것을 확인하지만, 매우 다르게 구조화했을 것입니다. 그럼에도 불구하고 그것이 작동하는 이유입니다.

0

performSelector 메서드를 호출하면 해당 afterDelay 기간이 발생합니다. 메서드가 큐에 대기하므로 winLabel.text = @ ""코드가 실행되고 그 후에 playWinSound 메서드가 실행되고, 레이블을 다시 변경하십시오.

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

이 메서드는 작업을 대기시키고 즉시 반환하고 텍스트를 ""로 다시 설정합니다. 실제로 기다렸다가 시간 초과 후 선택기를 호출하면 자원을 낭비합니다.

그러면 작업이 시간 초과 후 실행되고 텍스트가 "WIN"으로 설정됩니다.

Apple reference :

이 방법은 현재 스레드의 실행 루프에 aSelector 메시지를 수행 할 수있는 타이머를 설정 ...

관련 문제