Closure captures 'escapingClosure' before it is declared

I get a "Closure captures 'escapingClosure' before it is declared" with the following code.

If I put 'escapingClosure' out of the func function(), no problem.
It tested with 3 levels of nesting, I had to put 'escapingClosure' out of all functions (at main level).

What do you thing of that?

    func function() {
        
        var escapingClosure: (() -> Void)?

        func execEscaping(closure: @escaping () -> Void) {
            escapingClosure = closure    //// <<< "Closure captures 'escapingClosure' before it is declared"
        }
        
        func execNonEscaping(closure: () -> Void) {
            closure()
        }

        class Klass {
            var prop = 0
            func go() {
                execEscaping { self.prop = 1 }
                execNonEscaping { prop = 2 }
            }
        }
        
        let klass = Klass()
        klass.go()
        print(klass.prop)
        
        escapingClosure?()
        print(klass.prop)
        
    }; function()

Got a better diagnosis on iOS Playground:

func go() {
  execEscaping { self.prop = 1 } // Class declaration cannot close over value `execEscaping` defined in outer scope
  execNonEscaping { prop = 2 } // Class declaration cannot close over value `execNonEscaping` defined in outer scope
}

I get the same issue I got on Playground !?!

You got 1 error on 'execEscaping' and 'execNonEspaping'.
I have only a problem 'execEscaping'

You'd probably get the same error on Xcode playground since they'd be using the same compiler. iPad's playground is different though.

Anyhow, it seems that Swift specifically reject using local function inside a class declaration (which does make sense when you think about capturing).

Effectively, It looks like is with class the problem comes.
It tried it replacing class by function I didn't get the issue.

I had a similar problem when restructuring some code and moving things around where

    let doCSS = false // -- "Closure captures 'doCSS' before it is declared"

was generating the same error and I could not move it to a higher level since the code was in an extension and would have had to have had the variable in a different file.

    var doCSS: Bool { get { return false } }

However the above "trick" of utilizing computed properties for adding variables to an extension worked fine and got around the error as well.

Terms of Service

Privacy Policy

Cookie Policy