我正在使用带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
充当断路器。注释中指出的问题是,尽管使用break
,NSLog
仍将在每个期间继续打印。完全打破使用DispatchQueue.main.asyncAfter
的for循环的更好方法是什么?
您可以利用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
}
}