Block retain cycles in Swift?
swift
Solution
To prevent a block from holding a strong reference to an object, you must define a capture list for the block.
The closure expression syntax is defined as follows:
{ ( /*parameters*/ ) -> /*return type*/ in
// statements
}
But this is extended later in the documentation to include a capture list. This effectively equates to the expression syntax being defined as follows:
{ [ /*reference type*/ /*object*/, ... ] ( /*parameters*/ ) -> /*return type*/ in
// statements
}
...where `/*reference type*/` can be either `weak` or `unowned`.
The capture list is the first thing to appear in the closure and it is optional. The syntax, as shown above is defined as one or more pairs of reference type followed by object; each pair is separated by a comma. For example:
[unowned self, weak otherObject]
Complete example:
var myClosure = {
[unowned self] in
print(self.description)
}
Note that an `unowned` reference is non-optional, so you don't need to unwrap it.
Hopefully that answers your question. You can read up more about ARC in Swift in the relevant section of the documentation.
You should pay particular attention to the difference between `weak` and `unowned`. It could be safer in your implementation to use `weak`, because using `unowned` assumes the object will never be nil. This may lead to your app crashing if the object has actually been deallocated before being used in your closure.
Using `weak` as the reference type, you should unwrap with `?`, as follows:
var myClosure = {
[weak self] in
print(self?.description)
}
Problem
Traditionally in Objc, we do weakSelf to prevent additional retain count for blocks. How does swift internally manage retain cycles that occur in blocks for Objc?