Reputation: 41480
I have seen a lot of code that uses closure to initialize a var or lazy var which refer to self without the weak self syntax. Doesn't that create a risk of a retain cycle? Why doesn't the compiler flag that? Should it be a mandatory thing to always use weak self or unowned self when using closure of any kind as a safety measure?
e.g.
class Test {
lazy var tableView: UITableView = {
let tableView = UITableView(frame: self.view.bounds, style: .plain)
tableView.delegate = self
tableView.dataSource = self
return tableView
}
}()
Upvotes: 2
Views: 2156
Reputation: 2635
Lazy variables that aren't closure properties are not retained by anything so there is no need to use [unowned self]
here:
class Test {
lazy var tableView: UITableView = {
let tableView = UITableView(frame: self.view.bounds, style: .plain)
tableView.delegate = self
tableView.dataSource = self
return tableView
}()
}
This is not to be confused with closure properties that are lazily defined! Then the closure captures self, which will create a retain cycle. In this case you are creating a strong reference via self.view.bounds so you should use [unowned self]
(you know in this case that the tableView shouldn't exist if the Test object doesn't).
class Test {
lazy var tableView: () -> UITableView = {
[unowned self] in
let tableView = UITableView(frame: self.view.bounds, style: .plain)
tableView.delegate = self
tableView.dataSource = self
return tableView
}
}
Further reading: https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/AutomaticReferenceCounting.html
https://krakendev.io/blog/weak-and-unowned-references-in-swift
Upvotes: 11