Objective-C中的控制流程

时间:2009-06-25 22:28:38

标签: iphone objective-c cocoa-touch

我正在通过Beginning iPhone Development。书中有这种方法:

-(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 个答案:

答案 0 :(得分:3)

是的,流 返回旋转方法。诀窍在于执行playWinSound方法的调用:

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

请注意方法的 afterDelay 部分。这会在0.5秒过后的第一个可用时间安排playWinSound的调用。具体来说,调用将在0.5秒过后的第一个运行循环开始时进行。在已经运行的运行循环中调用此方法,因此playWinSound方法在spin方法返回后才能执行。

也就是说,这似乎是构建程序的一种非常奇怪的方式。我假设他们将winLabel.text设置为@""以确保将其重置为空字符串,除非它特别变为@"Win!",但我的结构却截然不同。然而,这就是它起作用的原因。

答案 1 :(得分:1)

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

此方法将操作排队,立即返回并将文本重置为“”。如果它实际等待,然后在超时后调用选择器,则会浪费资源。

然后在超时后执行操作,并将文本设置为“WIN”。

Apple reference

  

此方法设置要执行的计时器   当前的aSelector消息   线程的运行循环......

答案 2 :(得分:0)

我认为发生的事情是通过调用performSelector方法,它得到了afterDelay周期...所以方法排队,winLabel.text = @“”代码执行,然后playWinSound方法触发,改变标签了。