5

Can anyone tell me why this code gives the error message "Argument of '#selector' does not refer to an '@objc' method, property or initializer"?

timer = Timer.scheduledTimer(timeInterval: 0.1, target: self, selector:#selector(updateTimer(until: 3)), userInfo: nil, repeats: true)   

Here's the function:

func updateTimer(until endTime: Int) { 
    counter -= 1
    timeLabel.text = String(counter)
    if counter == endTime {
        step += 1
    }
}

What I have tried:
1. Adding @objc in front of the function.

skytect
  • 387
  • 3
  • 15

1 Answers1

5

The selector of a target / action method must be declared either without parameter or with one parameter passing the affected object.

In case of a Timer use the userInfo parameter to pass data.

timer = Timer.scheduledTimer(timeInterval: 0.1, target: self, selector:#selector(updateTimer(_:)), userInfo: 3, repeats: true)   


func updateTimer(_ timer: Timer) { 
    let endTime = timer.userInfo as! Int
    counter -= 1
    timeLabel.text = String(counter)
    if counter == endTime {
        step += 1
    }
}

If the enclosing class does not inherit form NSObject you have to add the @objc attribute to the action method.

vadian
  • 274,689
  • 30
  • 353
  • 361
  • For timers the parameter is required. *The selector should have the following signature: timerFireMethod: (including a colon to indicate that the method takes an argument).* Side note - Also, in Swift 4 the `@objc` or `@obcMembers` on the class is probably required. – Sulthan Jun 12 '17 at 07:43
  • 1
    @Sulthan That's not true. `updateTimer()` without parameter works, too. *should have* is not *must have* ;-) – vadian Jun 12 '17 at 07:49