在 Swift Closure 中调用 Nested function,会造成 circle retain 吗?
写了一个 demo:
import UIKit
class A {
let b: B?
init(b: B?) {
self.b = b
}
deinit {
print("deinit a")
}
func test() {
func __nestedFunction() {
print("nested function")
}
b?.block = {
__nestedFunction()
}
}
func test2() {
print("test 2")
}
}
class B {
var block: (() -> Void)?
deinit {
print("deinit b")
}
func excuteBlock() {
block?()
}
}
var b: B? = B()
var a: A? = A(b: b)
a?.test()
b?.excuteBlock()
b = nil
a = nil
nested function
deinit a
deinit b
可以看到两个 object 的 deinit 都有调用到,个人理解 nested 和内联函数类似,只是方法的替换。
在编程中,函数内联 是一种编译器优化技术,它通过使用方法的内容替换直接调用该方法,就相当于假装该方法并不存在一样,这种做法在很大程度上优化了性能。
但是要注意,如果 nested function 中调用了外部方法,还是会造成循环引用:
import UIKit
class A {
let b: B?
init(b: B?) {
self.b = b
}
deinit {
print("deinit a")
}
func test() {
func __nestedFunction() {
test2()
print("nested function")
}
b?.block = {
__nestedFunction()
}
}
func test2() {
print("test 2")
}
}
class B {
var block: (() -> Void)?
deinit {
print("deinit b")
}
func excuteBlock() {
block?()
}
}
var b: B? = B()
var a: A? = A(b: b)
a?.test()
b?.excuteBlock()
b = nil
a = nil
test 2
nested function
为了防止隐性的循环引用,建议使用 block 或者把嵌套函数放到外面。