Can't make weak reference to closure in Swift

closures, objective-c-blocks, retain-cycle, swift, weak-references

Solution

Looks like this isn't possible at the moment; you might want to file a bug.

But you can use an actual `func`tion to achieve the same thing:

func fib(n: Int) -> Int {
    if n < 2 {
        return n
    } else {
        return fib(n-1) + fib(n-2)
    }
}

fib(10) // 55

Computer science fun time! For a more direct translation of your code, we can use the Z combinator, with help from Swift's built-in curried function definitions:

func Z<T, U>(f: (T -> U, T) -> U)(x: T) -> U {
    return f(Z(f), x)
}

let fib = Z { (fib: Int -> Int, n: Int) in
    if n < 2 {
        return n
    } else {
        return fib(n-1) + fib(n-2)
    }
}

fib(x: 10) // 55

// (Note the name 'x' should not be required here.
//  It seems seems to be a bug in Beta 3, since the curried function in the
//  Swift guide doesn't work as advertised either.)

Problem

Update: I tried writing it without making it weak, and there doesn't seem to be a leak. So maybe the question is no longer necessary. In Objective-C ARC, when you want to have a closure be able to use itself inside of the closure, the block cannot capture a strong reference to itself, or it will be a retain cycle, so instead you can make the closure capture a weak reference to itself, like so: ``` // This is a simplified example, but there are real uses of recursive closures int (^fib)(int); __block __weak int (^weak_fib)(int); weak_fib = fib = ^(int n) { if (n < 2) return n; else return weak_fib(n-1) + weak_fib(n-2); }; ``` I tried to translate this to Swift: ``` var fib: (Int -> Int)? fib = { [weak fib] (n: Int) in // 'weak' cannot be applied to non-class type 'Int -> Int' if n < 2 { return n } else { return fib!(n-1) + fib!(n-2) } } ``` However, the Swift compiler won't allow me to declare a function to be captured weakly (`'weak' cannot be applied to non-class type 'Int -> Int'`). `[unowned fib]` also doesn't work (`'unowned' cannot be applied to non-class type '(Int -> Int)?'`). I know that functions are not class types in Swift. However, they are reference types and they do participate in reference counting. Therefore, shouldn't there be a way to make them weak or unowned references? How would I write a recursive closure in Swift that doesn't have a retain cycle?

Original source

Related problems