UPDATE: This bug is confirmed by rdar://20931915 and is fixed in Xcode 7 beta 3.
I found a weird bug caused by calling a swift closure in another closure in debug build. 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 its call() method, it will print "in closure 2" infinitely and eventually overflow the stack.
Could you please explain why calling one closure within another will cause this bug?
Thanks.
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 declare [weak self] in
in the function,and it cause the problem.
I also test this to call
let c = ClosureStackOverflow()
c.call()
It will output
in closure 1
in closure 2
deinit
It seems that it does not cause circular references if you donot use weak self
Besides I also test to change the function to this
func call() {
callClosure1 {
[weak self] in
self!.callClosure2 {
self?.b = true
}
}
}
It will work as well. So I think this may be some compiler bug of swift.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With