I'd like to ask if retain cycle happens in this situation:
func someFunc() {
var aVar = SomeObj()
funcWithClosure(something, completionHandler: { _ -> Void in
aVar = SomeObj() // new
})
}
In this case, I refer back to aVar from the closure. I just wonder if this creates a retain cycle. If true, should I fix by:
func someFunc() {
var aVar = SomeObj()
funcWithClosure(something, completionHandler: { [weak aVar] _ -> Void in
aVar = SomeObj() // new
})
}
Just to expand on your question, you would get a retain cycle if aVar
strongly references the closure. For example:
func someFunc() {
var aVar = SomeObj()
aVar.funcWithClosure(something, completionHandler: {
doSomethingWith(aVar)
}
}
aVar
strongly references the closure because it calls the function, and the closure strongly references aVar
because it uses the variable in its body. To break the cycle, you could create a weak reference to aVar
outside the closure, like this:
func someFunc() {
var aVar = SomeObj()
weak var weakVar = aVar
aVar.funcWithClosure(something, completionHandler: {
if let weakVar = weakVar {
doSomethingWith(weakVar)
}
}
}
weakVar
references aVar
, so you use it in the place of aVar
. And it references it weakly, so when aVar
goes out of scope (when the function completes), its ref count can become zero. Inside the closure, since weakVar
is a weak var, need to unwrap it somehow before using.
In your question, you proposed adding [weak aVar]
to the closure's capture list, which I don't believe would work.
EDIT: fixed unwrapping weakVar
as var
, which is a keyword.