Stack overflow caused by fast close in another close

UPDATE: This bug is confirmed by rdar: // 20931915 and fixed in Xcode 7 beta 3.


I found a strange error caused by calling quick close in another closure in debug assembly. My Xcode is version 6.3.1 with Swift version 1.2. Here's the code:

import Swift

class ClosureStackOverflow {
    private var b: Bool = false
    private func callClosure1(callback: Void -> Void) {
        println("in closure 1")
        callback()
    }

    private func callClosure2(callback: Void -> Void) {
        println("in closure 2")
        callback()
    }

    func call() {
        callClosure1 { [weak self] in
            self?.callClosure2 {
                self?.b = true
            }
        }
    }
}

let c = ClosureStackOverflow()
c.call()

      

The code above compiles well. However, if you call your call () method, it will print infinitely "at close 2" and eventually overflow the stack.

Could you please explain why calling one closure inside another would result in this error?

Thank.

+3


source to share


1 answer


Change your code to this and it will work

    class ClosureStackOverflow {
    private var b: Bool = false
    private func callClosure1(callback: Void -> Void) {
        println("in closure 1")
        callback()
    }

    private func callClosure2(callback: Void -> Void) {
        println("in closure 2")

        callback()
    }

    func call() {
        callClosure1 {
            self.callClosure2 {
                self.b = true
            }
        }
    }
    deinit{
        print("deinit")
    }
}

      

It seems that you are declaring [weak self] in

in a function and that is causing the problem.

I also check this against a call

 let c = ClosureStackOverflow()
    c.call()

      

He will output



 in closure 1
in closure 2
deinit

      

It doesn't seem to trigger circular references unless you use weak me

Also, I also check to change the function to this

  func call() {
    callClosure1 {
        [weak self] in
        self!.callClosure2 {
            self?.b = true
        }
    }
}

      

This will work too. So I think it might be a Quick compiler error.

+1


source







All Articles