【问题标题】:How to handle class methods being called again before they are finished?如何处理在完成之前再次调用的类方法?
【发布时间】:2011-04-07 16:44:52
【问题描述】:

在 iPhone 设备上处理这种情况的最佳方法是什么:我的程序在两个值之间调整声音的音高。按下按钮调用一个方法,该方法具有一个 while 循环,该循环以小增量进行斜坡。这需要一些时间才能完成。与此同时,用户按下了另一个调用相同方法的按钮。现在我希望第一次调用中的循环停止,第二次调用从当前状态开始。这是该方法的外观:

-(void)changePitchSample: (float) newPitch{
float oldPitch=channel.pitch;
if (oldPitch>newPitch) {
    while (channel.pitch>newPitch) {
        channel.pitch = channel.pitch-0.001;
    }
}
else if (oldPitch<newPitch) {
    while (channel.pitch<newPitch) {
        channel.pitch = channel.pitch+0.001;
    }
}

}

现在如何最好地处理再次调用该方法的情况?我需要某种多线程吗?我不需要两个进程同时进行,所以似乎必须有一些我找不到的更简单的解决方案(对这种语言不熟悉)。

非常感谢任何帮助!

【问题讨论】:

    标签: iphone objective-c xcode ios


    【解决方案1】:

    你不能那样做。当您的循环运行时,不会处理任何事件。因此,如果用户再次按下按钮,则在您的循环完成之前不会发生任何事情。同样像这样,您无法控制坡道的速度。我建议使用 NSTimer。在您的changePitchSample: 方法中,您将新音高存储在某处(不要覆盖旧音高)并启动一个触发一次的计时器。当计时器触发时,你增加你的音高,如果它小于新的音高,你重新启动计时器。

    【讨论】:

    • 谢谢。我在某处读到 NSTimer 的分辨率为 100 毫秒左右,但我自己还没有测试过(很可能是错误的)。这样的分辨率当然无法顺利进行。
    • 你说得对,Apple 的文档说大约 50-100 毫秒。确切的分辨率还取决于运行循环中发生的其他事情。我会试试计时器,看看它是否足够好。否则你可能不得不使用另一个线程。
    • 是的,这种时间间隔不适用于音高,因为它需要非常平滑。所以我仍然需要研究线程。 . .
    【解决方案2】:

    看看NSOperationConcurrency Programming Guide。您可以先开始操作,增加音高,也可以存储操作对象。在第二次通话中,您可以拨打[operation cancel] 停止最后一次操作。开始第二个操作,即减小音高并存储新对象。

    顺便说一句:你现在做的很糟糕,因为你“阻塞了主线程”。不应该直接执行需要一些时间的计算。您可能还应该看看 NSTimer 以使您的代码独立于处理器速度。

    【讨论】:

    • 谢谢,我会研究 NSOperation,但我可能仍需要某种多线程,正如您从其他关于 NSTimer 不够快的答案中看到的那样。
    • @materialvision:如果你需要线程,NSOperation 是最简单的方法。
    • @materialvision: NSOperation 一种执行多线程的方法。操作队列为其上的每个操作生成一个新线程。
    【解决方案3】:

    不要使用while循环;它阻止了其他一切。使用定时器和状态机。计时器可以按照您希望更改的速率调用状态机。状态机可以查看最后一个斜坡值和最后一次按下按钮的时间(甚至是 UI 事件时间数组),并决定在下一个时间步长是否以及增加多少音量(逻辑通常只是一堆if 和 select/case 语句,如果控制算法不适合一个漂亮的表)。然后状态机可以调用处理实际声级的对象或例程。

    【讨论】:

    • 谢谢,但正如您在上面关于 NSTimer 的其他答案的讨论中看到的那样,它没有足够大的分辨率来处理音高(这会导致非常可听的步骤)。我可能需要在单独的线程或类似的东西中运行状态机。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-01-04
    • 1970-01-01
    • 1970-01-01
    • 2017-03-05
    • 2012-08-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多