It is a very common technique to create generic recursive closures in swift, like that demonstrated in WWDC2014 Advanced Swift Session.
But somehow I find it is very possibile to create a Strong Reference Cycle with it.
Here is the simple code. I used the foo function scope to simulate life cycle, beyond which all objects are supposed to dealloc.
class Nested {
func print() {
println("Print Nested")
}
deinit {
println("Nested dealloc")
}
}
typealias ClosureType = Int -> Int
func foo() {
var myClosure : ClosureType = {
value in value
}
func setClosure() {
var date = Nested()
myClosure = {
input in
date.print()
return input <= 1 ? 1 : input + myClosure(input - 1)
}
}
// do something
setClosure()
println(myClosure(5))
}
// test it
foo()
the output didn't include the deinit string
I think it is because myClosure is capturing itself. It is not a very big memory leak until some extra objects are involved (like that Nested object which may contain very large amount of objects).The problem is when I no longer need that closure, I can't find anyway to dealloc it.
There are some workaround, for example: you can add another layer between the closure and the caller, so that the strong reference cycle occurs between the mid-layer and the closure rather than inside that closure itself, making it possible for you to free the closure manually.
But in this certain case I can't find any of them elegant :you cannot sepecify a weak reference to a closure at the moment, nor can you add a capture list for a closure outside class definitions.
Hope anyone can give me a solution.