2009-06-25 66 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!」。爲什麼如果旋轉結果爲win,則winLabel中的文本變爲@「Win!」並保持這種方式。流程不應該返回到將winLabel更改爲@「」的旋轉方法?

回答

3

是的,流程確實返回到自旋方法。關鍵是在其中正在執行方法playWinSound呼叫:

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

注方法的afterDelay部。這會在經過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消息...