Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
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

This comment has been minimized.

Copy link

@vin-zhou vin-zhou commented Jan 25, 2018

@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

This comment has been minimized.

Copy link

@lyc2345 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