Swift:我的 NSTimer 有问题吗?
Swift: Issue with my NSTimer?
所以一般来说,这就是我想要我的程序做的:音乐会播放,随机生成一个 3 到 12 之间的数字,然后根据该数字设置一个计时器,当计时器结束时停止音乐播放 1 秒,然后播放 1 秒后,再次播放音乐(并重复该过程,生成随机数...)
这是我为此编写的代码,第一个 运行 效果很好,但第二个 运行 它开始以更快的速度调用函数(不遵循计时器)有时顺序不同(您可以通过查看打印输出来测试)
var randomTimeInteger = Int()
var stopMusicTimer = NSTimer()
var startMusicTimer = NSTimer()
override func viewDidLoad(){
playMusic()
}
//Call to get random interger
func generateRandomInteger(){
print("Inside generate random integer")
let lower = 3
let upper = 12
randomTimeInteger = lower + Int(arc4random_uniform(UInt32(upper - lower + 1)))
print("Random Integer is : \(randomTimeInteger)")
initiateTimer()
}
//Start the timer
func initiateTimer() {
print("Inside initate Timer")
//Set Timer
stopMusicTimer = NSTimer.scheduledTimerWithTimeInterval(Double(randomTimeInteger), target: self, selector: "stopMusic", userInfo: nil, repeats: true)
}
//Stop the music
func stopMusic(){
print("Inside stop music")
GameViewController.backgroundAudio?.stop()
startMusicTimer = NSTimer.scheduledTimerWithTimeInterval(3.0, target: self, selector: "playMusic", userInfo: nil, repeats: true)
}
func playMusic(){
print("Inside play music")
GameViewController.backgroundAudio?.play()
generateRandomInteger()
}
知道问题出在哪里吗?或者是否有更好的方法?请帮忙!
您有一个计时器,每 3 到 12 秒尝试停止一次音乐。有时您会创建一个计时器,尝试每 3 秒启动一次音乐。有时您会创建更多此类计时器。所以最终你会有很多很多的定时器,它们会尝试在随机时间开始和停止音乐。
要停止重复计时器,请调用 invalidate。
并且不要像您那样初始化计时器,NSTimer() returns 没有任何用处。只需将变量声明为 NSTimer?
确实有很多可行的方法。
从头开始,我会草图设计如下:
func playMusic(completion: (ErrorType?)->()) {
play(randomDuration()) { error in
if error != nil {
completion(error)
return
}
delay(1.0, f: play)
}
}
func randomDuration() -> Double {...}
func play(duration: Double, completion: (ErrorType?)->()) {
let player = Player(...)
player.resume()
delay(duration) {
player.suspend()
completion(nil)
}
}
函数delay(_:f:)
是根据dispatch_after
实现的。
您可能会注意到,playMusic
会无限期地运行。这是您的要求,但实际上您需要一种方法来阻止它。
所以一般来说,这就是我想要我的程序做的:音乐会播放,随机生成一个 3 到 12 之间的数字,然后根据该数字设置一个计时器,当计时器结束时停止音乐播放 1 秒,然后播放 1 秒后,再次播放音乐(并重复该过程,生成随机数...)
这是我为此编写的代码,第一个 运行 效果很好,但第二个 运行 它开始以更快的速度调用函数(不遵循计时器)有时顺序不同(您可以通过查看打印输出来测试)
var randomTimeInteger = Int()
var stopMusicTimer = NSTimer()
var startMusicTimer = NSTimer()
override func viewDidLoad(){
playMusic()
}
//Call to get random interger
func generateRandomInteger(){
print("Inside generate random integer")
let lower = 3
let upper = 12
randomTimeInteger = lower + Int(arc4random_uniform(UInt32(upper - lower + 1)))
print("Random Integer is : \(randomTimeInteger)")
initiateTimer()
}
//Start the timer
func initiateTimer() {
print("Inside initate Timer")
//Set Timer
stopMusicTimer = NSTimer.scheduledTimerWithTimeInterval(Double(randomTimeInteger), target: self, selector: "stopMusic", userInfo: nil, repeats: true)
}
//Stop the music
func stopMusic(){
print("Inside stop music")
GameViewController.backgroundAudio?.stop()
startMusicTimer = NSTimer.scheduledTimerWithTimeInterval(3.0, target: self, selector: "playMusic", userInfo: nil, repeats: true)
}
func playMusic(){
print("Inside play music")
GameViewController.backgroundAudio?.play()
generateRandomInteger()
}
知道问题出在哪里吗?或者是否有更好的方法?请帮忙!
您有一个计时器,每 3 到 12 秒尝试停止一次音乐。有时您会创建一个计时器,尝试每 3 秒启动一次音乐。有时您会创建更多此类计时器。所以最终你会有很多很多的定时器,它们会尝试在随机时间开始和停止音乐。
要停止重复计时器,请调用 invalidate。
并且不要像您那样初始化计时器,NSTimer() returns 没有任何用处。只需将变量声明为 NSTimer?
确实有很多可行的方法。
从头开始,我会草图设计如下:
func playMusic(completion: (ErrorType?)->()) {
play(randomDuration()) { error in
if error != nil {
completion(error)
return
}
delay(1.0, f: play)
}
}
func randomDuration() -> Double {...}
func play(duration: Double, completion: (ErrorType?)->()) {
let player = Player(...)
player.resume()
delay(duration) {
player.suspend()
completion(nil)
}
}
函数delay(_:f:)
是根据dispatch_after
实现的。
您可能会注意到,playMusic
会无限期地运行。这是您的要求,但实际上您需要一种方法来阻止它。