The timer methods with the selector must have one parameter: the timer itself. So your code should look like this: 1
Timer.scheduledTimer(timeInterval: 1.1, target: self, selector: #selector(self.adjustmentBestSongBpmHeartRate(_:), userInfo: nil, repeats: false) @objc func adjustmentBestSongBpmHeartRate(_ timer: Timer) { print("frr") }
Please note that if your application only runs on iOS> = 10, you can use the new method, which uses a block rather than a target / selector to call. Much cleaner and safer:
class func scheduledTimer(withTimeInterval interval: TimeInterval, repeats: Bool, block: @escaping (Timer) -> Void) -> Timer
This code will look like this:
timer = Timer.scheduledTimer(withTimeInterval: 1.1, repeats: false) { timer in //Put the code that be called by the timer here. print("frr") }
Note that if your timer / close block needs access to instance variables from your class, you should be especially careful with self
. Here is a good template for this kind of code:
timer = Timer.scheduledTimer(withTimeInterval: 1.1, repeats: false) { //"[weak self]" creates a "capture group" for timer [weak self] timer in //Add a guard statement to bail out of the timer code //if the object has been freed. guard let strongSelf = self else { return } //Put the code that be called by the timer here. print(strongSelf.someProperty) strongSelf.someOtherProperty = someValue }
Edit:
1 : I have to add that the method you use in the selector should use Objective-C dynamic dispatch. You can declare a method using the @objc
qualifier, you can declare an entire class that defines a selector using the @objc
qualifier, or you can make a class that defines a selector a subclass of NSObject
or any class that inherits from NSOBject
. (Quite often, a method is defined that the timer calls inside the UIViewController
, which is a subclass of NSObject
, so it "just works."
EDIT
In Swift 4, methods that must be called from Objective-C must now be individually tagged with the @objc
qualifier. The comment βit just worksβ is no longer true.