【问题标题】:Control flow in Objective-CObjective-C 中的控制流
【发布时间】:2009-06-25 22:28:37
【问题描述】:

我正在通过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更改为@“”的spin方法吗?

【问题讨论】:

    标签: iphone objective-c cocoa-touch


    【解决方案1】:

    是的,流程确实返回到 spin 方法。诀窍在于执行playWinSound 方法的调用:

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

    注意该方法的 afterDelay 部分。这会在 0.5 秒后的第一个可用时间安排对 playWinSound 的调用。具体来说,调用将在第一个运行循环开始时发生 0.5 秒后。这个方法在一个已经运行的运行循环中被调用,所以playWinSound 不可能在spin 方法返回之后执行。

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

    【讨论】:

      【解决方案2】:
      [self performSelector:@selector(playWinSound) withObject:nil afterDelay:.5];
      

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

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

      Apple reference:

      这个方法设置一个定时器来执行 当前的 aSelector 消息 线程的运行循环...

      【讨论】:

        【解决方案3】:

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2023-03-24
          • 1970-01-01
          • 2014-07-05
          • 2011-07-10
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多