Implementing NSTimer into Code - Swift

2019-08-06 15:43发布

问题:

I am having a bit of trouble using / implementing NSTimer into code. So far, i have this:

//Delay function from http://stackoverflow.com/questions/24034544/dispatch-after-gcd-in-swift/24318861#24318861
func delay(delay:Double, closure:()->()) {
    dispatch_after(
        //adds block for execution at a specific time
        dispatch_time(
            //creates a dispatch time relative to default clock
            DISPATCH_TIME_NOW,
            //Indicates that something needs to happen imediately
            Int64(delay * Double(NSEC_PER_SEC))
            //a 64bit decleration that holds the delay time times by the amount of nanoseconds in one seconds, inorder to turn the 'delay' input into seconds format
        ),
        dispatch_get_main_queue(), closure)
}


@IBAction func computerTurn(){

    if(isFirstLevel){levelLabel.text = ("Level 1"); isFirstLevel = false}
    else{ level++ }

    var gameOrderCopy = gameOrder
    var randomNumber = Int(arc4random_uniform(4))
    gameOrder.append(randomNumber)
    var i = 0
    var delayTime = Double(1)

    println(Double(NSEC_PER_SEC))
    for number in self.gameOrder{


        if number == 0{
            delay(delayTime++){self.greenButton.highlighted = true}
            self.delay(delayTime++){
                self.greenButton.highlighted = false
            }
        }

        else if number == 1{
            delay(delayTime++){self.redButton.highlighted = true}
             self.delay(delayTime++){
                self.redButton.highlighted = false
            }

        }

        else if number == 2{
            delay(delayTime++){self.yellowButton.highlighted = true}
             self.delay(delayTime++){
                self.yellowButton.highlighted = false
            }
        }
        else if number == 3{
            delay(delayTime++){self.blueButton.highlighted = true}
             self.delay(delayTime++){
                self.blueButton.highlighted = false
            }
        }
        println(delayTime)


    }
}

What i need to do, is replace the timer function, or get rid of it, and do the same as whats happening here, but using NSTimer.

Thanks

回答1:

NSTimer can be a little clunky in this context because it requires using either target-action or NSInvocation. However, NSTimer is toll-free bridged with CFRunLoopTimer, which you can call with a block:

func delay(delay:Double, closure:()->()) {
    let fireDate = delay + CFAbsoluteTimeGetCurrent()
    let timer = CFRunLoopTimerCreateWithHandler(kCFAllocatorDefault, fireDate, 0, 0, 0) { _ in
        closure()
    }
    CFRunLoopAddTimer(CFRunLoopGetCurrent(), timer, kCFRunLoopCommonModes)
}


回答2:

I would suggest:

  • Setting up some class property to maintain the "current" numeric index (which you'd start at 0);

  • Start your repeating timer;

  • The timer's handler would use the index to figure out which button to change and then do one "turn highlight on" and then do a dispatch_after for the "turn highlight back off";

    Then, this handler would look at the index and determine if you're at the end of the list or not. If you are, then cancel the timer and you're done. If you're not at the end of the list, then increment the "current index" and wait for the next scheduled timer fire off.



标签: swift nstimer