2016-02-25 2 views
1

Итак, в общем, это то, что я хочу, чтобы моя программа выполняла: музыка будет воспроизводить, произвольно генерировать число от 3 до 12, а затем установить таймер в соответствии с этим номером, когда таймер закончен, остановите музыку в течение 1 секунды , затем после этого одну секунду снова воспроизведите музыку (и повторите процесс, создайте случайное число ...)Swift: проблема с моим NSTimer?

Это код, который я написал для этого, он отлично работает, первый запуск, но второй запуск она начинает вызывать функции на более быстрыми темпами (не после таймера), а иногда и в другом порядке (вы можете проверить это, глядя на распечатки)

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

У вас есть один таймер, который пытается остановить музыку каждые 3 - 12 секунд. И иногда вы создаете таймер, который пытается начать музыку каждые 3 секунды. И иногда вы создаете больше этих таймеров. Поэтому, в конце концов, у вас много и много таймеров, которые пытаются запускать и останавливать музыку в произвольное время.

Чтобы остановить повторный таймер, вызовите invalidate.

И не инициализируйте таймеры так же, как вы, NSTimer() ничего не возвращает. Просто объявите переменные как NSTimer?

+0

Удивительно. Я не знаю, почему я этого не видел. спасибо – OriginalAlchemist

0

Есть действительно множество жизнеспособных подходов.

Начиная с вершины, я бы эскиз дизайн следующим образом:

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 работает на неопределенный срок. Это по вашим требованиям, но на практике вам нужен способ его остановить.