Pawan Kumar Singh
Pawan Kumar Singh

Reputation: 3

Swift 3.0: Timer not firing for target other than self

Timer.scheduledTimer(timeInterval: 5.0, target:self.notificationView, selector: #selector(NotificationView.self.timerFired(_:)), userInfo: nil, repeats: false)

func timerFired(_ timer: Timer) {
        print("Timer Fired")
}

*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[_SwiftValue timerFired:]: unrecognized selector sent to instance 0x7fc0baf46f60'

I don't understand where is wrong? If target is self then everything works fine.

Upvotes: 0

Views: 2432

Answers (4)

Anand
Anand

Reputation: 864

The code below worked for me (in playground/swift 3) :

class SomeClass {

    @objc public func timerFired(_ timer: Timer) {
        print("Timer Fired")
    }
}

let s = SomeClass()

Timer.scheduledTimer(timeInterval: 5.0, target:s, selector: #selector(s.timerFired(_:)), userInfo: nil, repeats: false).fire()
//This also will work
//Timer.scheduledTimer(timeInterval: 5.0, target:s, selector: #selector(SomeClass.timerFired(_:)), userInfo: nil, repeats: false).fire()

Upvotes: 0

Wilson
Wilson

Reputation: 9136

I try the following code and NotificationView.timerFired is triggered:

class NotificationView {
  @objc func timerFired(_ timer: Timer) {
    print("Timer Fired")
  }
}

class ViewController: UIViewController {
  let notificationView = NotificationView()

  override func viewDidLoad() {
    super.viewDidLoad()

    Timer.scheduledTimer(
      timeInterval: 5.0, 
      target:self.notificationView, 
      selector: #selector(NotificationView.timerFired(_:)), 
      userInfo: nil, 
      repeats: false
    )

  }
}

Upvotes: 1

OOPer
OOPer

Reputation: 47876

Check this part of your error message:

[_SwiftValue timerFired:]

timerFired: is an Objective-C style notation of the selector. Seems your #selector(...) is working. (Though not recommended...)

_SwiftValue is a class name of the object being the target of the selector. This means your target target:self.notificationView is converted to _SwiftValue.

This may happen when you declare your notificationView as Optional or implicitly unwrapped Optional. If so, try this:

Timer.scheduledTimer(timeInterval: 5.0, target: self.notificationView!, selector: #selector(NotificationView.timerFired(_:)), userInfo: nil, repeats: false)

(Please do not miss the ! after self.notificationView.)

Upvotes: 0

Nirav D
Nirav D

Reputation: 72410

The problem is with your selector syntax it will be like this.

#selector(NotificationView.timerFired(_:))

Note : self is for current ViewController if you want to set action for another then you need to specify the class name.method in your case it is NotificationView.timerFired.

Upvotes: 1

Related Questions