I have some function inside another function. in function1 i want to use NSTimer to call func2 after some time like this:
func myFunc1()
{
NSTimer.scheduledTimerWithTimeInterval(1, target: ??, selector:#selector(myFunc2()), userInfo: nil, repeats: false)
func myFunc2()
{
// do something...
}
}
What is the right "target" value that i should pass there? is it even possible?
If you are targeting pre-iOS 10, you can't pass a function to NSTimer
because no API was introduced at that time to support closure callbacks.
iOS 10 and later Approach
// swift 2.x users should still use NSTimer instead
Timer.scheduledTimer(withTimeInterval: 2.0, repeats: true) { timer in
// ...
}
Generic Approach
You can add this class, and reuse it anytime:
final class TimerInvocation: NSObject {
var callback: () -> ()
init(callback: @escaping () -> ()) {
self.callback = callback
}
func invoke() {
callback()
}
}
extension Timer {
static func scheduleTimer(timeInterval: TimeInterval, repeats: Bool, invocation: TimerInvocation) {
Timer.scheduledTimer(
timeInterval: timeInterval,
target: invocation,
selector: #selector(TimerInvocation.invoke(timer:)),
userInfo: nil,
repeats: repeats)
}
}
With this class, you can simply do this now:
let invocation = TimerInvocation {
/* invocation code here */
}
NSTimer.scheduledTimerWithTimeInterval(1, target: invocation, selector:#selector(TimerInvocation.invoke), userInfo: nil, repeats: false)
You don't have to worry about retaining the invocation
variable since it is retained by NSTimer
In Swift 3, the new Timer
has a factory method that takes a closure:
Timer.scheduledTimer(withTimeInterval: TimeInterval, repeats: Bool, block: (Timer) -> Void)
In your case, you could call it like this using trailing closure syntax:
Timer.scheduledTimer(withTimeInterval: 1, repeats: false) { _ in
// do something
}
Note: This is only available in iOS 10 or newer.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With