1

I create a simple WatchApp Metronome. I use NSTimer with .scheduledTimerWithTimeInterval, and I have an error Extra Argument 'selector' in call

Thanks for your answers

func playBeat() {

        if(self.State == true) {
            self.State == false
            [labelPlayPause.setTitle("Pause")]
        } else {
            self.State == true
            [labelPlayPause.setTitle("Play")]
        }

        BPMValue = 10
        var BPMInt:Int = Int(BPMValue)
        let value = "\(BPMInt) BPM"
        labelBPM.setText(value)
        let aSelector: Selector = "playBeat"

        dispatch_async(dispatch_get_main_queue(), {
            NSTimer.scheduledTimerWithTimeInterval(60/self.BPMValue, target:self, selector: aSelector, userInfo:nil, repeats:false)
        })

    }
Ashley Mills
  • 50,474
  • 16
  • 129
  • 160
Kevin Py
  • 2,459
  • 2
  • 22
  • 33

1 Answers1

6

This is a poor error message from Swift!

What this really means is that you need to ensure the types of each function parameter match the types of the values passed.

In your case, BPMValue is a Float, and scheduledTimerWithTimeInterval is expecting and NSTimeInterval as its first parameter. Note that NSTimeInterval (Double) and Float are not equivalent. In Objective-C you get an implicit conversion, this doesn't happen in Swift.

Try

NSTimer.scheduledTimerWithTimeInterval(NSTimeInterval(60/self.BPMValue), target:self, selector: aSelector, userInfo:nil, repeats:false)

As a side note, you can be a little more terse with your code in Swift:

func playBeat() {

    if State {          // If State is a Bool, you can lose the '== true'
        State = false   // Must use set not comparison operator. No need to refer to 'self'.
        labelPlayPause.setTitle("Pause")
    } else {
        State = true  // Must use set not comparison operator.
        labelPlayPause.setTitle("Play")
    }

    BPMValue = 10
    var BPMInt = Int(BPMValue)    // Int Type is inferred
    let value = "\(BPMInt) BPM"
    labelBPM.setText(value)
    let aSelector: Selector = "playBeat"

    dispatch_async(dispatch_get_main_queue(), {
        NSTimer.scheduledTimerWithTimeInterval(NSTimeInterval(60/self.BPMValue), target:self, selector: aSelector, userInfo:nil, repeats:false)
    })

}
Duncan Babbage
  • 19,972
  • 4
  • 56
  • 93
Ashley Mills
  • 50,474
  • 16
  • 129
  • 160
  • I don't unserstand. BPMValue isn't Int, but a float. I convert BPMValue to Int for display in Label (BPMInt). I use in NSTimer the BPMValue as a float, no ? – Kevin Py Jan 10 '15 at 10:22
  • No, NSTimeInterval is a typeAlias for Double, which is not equivalent to Float, so you cannot pass a float to it. – Dániel Nagy Jan 10 '15 at 10:47
  • So you have to add either a Double, or an NSTimeInterval, but not a Float. – Dániel Nagy Jan 10 '15 at 10:53
  • 1
    Have added edit noting that the original code uses comparison operators in two cases where it should be using set operators. – Duncan Babbage Jan 10 '15 at 20:53