Skip to content

Instantly share code, notes, and snippets.

@alanf
Last active January 20, 2017 23:48
Show Gist options
  • Save alanf/cee87d89be6863eeab479b57f63e2811 to your computer and use it in GitHub Desktop.
Save alanf/cee87d89be6863eeab479b57f63e2811 to your computer and use it in GitHub Desktop.
Illustrates a specific type of retain cycle
/// Schedules a timer on a queue when the view is loaded.
/// Also logs when deinit is invoked
class ViewControllerBase: UIViewController {
let timer:DispatchSourceTimer = DispatchSource.makeTimerSource(flags: [], queue: DispatchQueue(label: "q.q"))
deinit {
NSLog("deinit of \(NSStringFromClass(type(of: self)))")
}
override func viewDidLoad() {
super.viewDidLoad()
timer.scheduleRepeating(deadline: .now(), interval: .seconds(1))
}
}
/// SUBTLE MEMORY LEAK ILLUSTRATED
/// Which of the following `ViewController`s:
/// - Leaks memory?
/// - Compiles with an error?
/// - Is correct?
class ViewControllerA: ViewControllerBase {
override func viewDidLoad() {
super.viewDidLoad()
timer.setEventHandler {
UIView.animate(withDuration: 0.2) {
self.view.backgroundColor = UIColor.green
}
}
}
}
class ViewControllerB: ViewControllerBase {
override func viewDidLoad() {
super.viewDidLoad()
timer.setEventHandler {
UIView.animate(withDuration: 0.2) {
NSLog("Hello")
}
}
}
}
class ViewControllerC: ViewControllerBase {
override func viewDidLoad() {
super.viewDidLoad()
timer.setEventHandler {
UIView.animate(withDuration: 0.2) { [weak self] in
NSLog("Hello")
}
}
}
}
class ViewControllerD: ViewControllerBase {
override func viewDidLoad() {
super.viewDidLoad()
timer.setEventHandler { [weak self] in
UIView.animate(withDuration: 0.2) {
self?.view.backgroundColor = UIColor.green
}
}
}
}
class ViewControllerE: ViewControllerBase {
override func viewDidLoad() {
super.viewDidLoad()
timer.setEventHandler {
UIView.animate(withDuration: 0.2) { [weak self] in
self?.view.backgroundColor = UIColor.green
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment