Skip to content

Instantly share code, notes, and snippets.

@onevcat
Created September 28, 2015 03:34
Show Gist options
  • Star 7 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save onevcat/2d1ceff1c657591eebde to your computer and use it in GitHub Desktop.
Save onevcat/2d1ceff1c657591eebde to your computer and use it in GitHub Desktop.
NSTimer extension which breaks the retain cycle in Swift.
private class Block<T> {
let f : T
init (_ f: T) { self.f = f }
}
extension NSTimer {
static func xxx_scheduledTimerWithTimeInterval(ti: NSTimeInterval, block: ()->(), repeats: Bool) -> NSTimer {
return self.scheduledTimerWithTimeInterval(ti, target:
self, selector: "xxx_blcokInvoke:", userInfo: Block(block), repeats: repeats)
}
static func xxx_blcokInvoke(timer: NSTimer) {
if let block = timer.userInfo as? Block<()->()> {
block.f()
}
}
}
@vin-zhou
Copy link

@onecat, if repeats = true and we don't call timer.invalidate() in the deinit of controllerA( i.e. the user of Timer) , the block will continue repeatedly called in the background. Anyway to solve it ?

@lyc2345
Copy link

lyc2345 commented Oct 18, 2018

@vin-zhou you can call invalidate in viewDidDisappear? Because run loop will maintain strong reference to timer, timer to ViewController. So call invalidate it first to release timer then ViewController.

Timers work in conjunction with run loops. To use a timer effectively, you should be aware of how run loops operate—see NSRunLoop and Threading Programming Guide. Note in particular that run loops maintain strong references to their timers, so you don’t have to maintain your own strong reference to a timer after you have added it to a run loop.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment