如何摆脱内部使用异步DispatchQueue的循环

问题描述 投票:0回答:1

我正在使用带DispatchQueue的for循环与具有异步功能的DispatchQueue结合,以在5或10分钟的持续时间内逐步增加播放量。

我目前的实施方式是:

    for i in (0...(numberOfSecondsToFadeOut*timesChangePerSecond)) {
        DispatchQueue.main.asyncAfter(deadline: .now() + Double(i)/Double(timesChangePerSecond)) {
            if self.activityHasEnded {
                NSLog("Activity has ended") //This will keep on printing
            } else {
                let volumeSetTo = originalVolume - (reductionAmount)*Float(i)
                self.setVolume(volumeSetTo)
            }
        }

        if self.activityHasEnded {
            break
        }
    }

我的目标是让activityHasEnded充当断路器。注释中指出的问题是,尽管使用breakNSLog仍将在每个期间继续打印。完全打破使用DispatchQueue.main.asyncAfter的for循环的更好方法是什么?

ios swift for-loop dispatch-async
1个回答
0
投票

您可以利用DispatchWorkItem,它可以异步地分派给DispatchQueue,甚至在分派后也可以取消。

for i in (0...(numberOfSecondsToFadeOut*timesChangePerSecond)) {
    let work = DispatchWorkItem {
        if self.activityHasEnded {
            NSLog("Activity has ended") //This will keep on printing
        } else {
            let volumeSetTo = originalVolume - (reductionAmount)*Float(i)
            self.setVolume(volumeSetTo)
        }
    }
    DispatchQueue.main.asyncAfter(deadline: .now() + Double(i)/Double(timesChangePerSecond), execute: work)
    if self.activityHasEnded {
        work.cancel() // cancel the async work
        break // exit the loop
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.