1、定義一個(gè)controller: TestController并添加如下代碼
class TestController: UIViewController {
typealias TestClosure = () -> ()
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .white
}
deinit {
print(self, #function)
}
// MARK: - private property
private var name: String = "sdf"
private var closure: TestClosure?
}
然后添加方法進(jìn)行測(cè)試:
-
1
func test() {
let closure: TestClosure = {
self.name = ""
}
closure()
}
不會(huì)循環(huán)引用
closure引用了name,但是 self 沒有引用closure,
不構(gòu)成互相強(qiáng)引用的關(guān)系
-
2
func test2() {
let closure: TestClosure = {
self.name = ""
}
closure()
self.closure = closure
}
會(huì)
closure引用了name,self 也引用closure,
構(gòu)成互相強(qiáng)引用的關(guān)系
-
3
func test3() {
let closure: TestClosure = {[weak self] in
let closure1: TestClosure = {
self?.name = "dddd"
}
closure1()
}
closure()
self.closure = closure
}
不會(huì)
closure中使用了[weak self] 修飾,所以在整個(gè)closure中的self都是弱引用,
雖然在closure1中并沒有用[weak self]關(guān)鍵字,但是他此時(shí)調(diào)用的self是closure中的弱引用self
所以沒有構(gòu)成循環(huán)引用
-
4
func test4() {
let closure: TestClosure = {
let closure1: TestClosure = { [weak self] in
self?.name = "dddd"
}
closure1()
}
closure()
self.closure = closure
}
會(huì)
closure中并沒有使用了[weak self] 修飾,所以在整個(gè)closure中的self都是強(qiáng)引用,
雖然在closure1中并有用[weak self]關(guān)鍵字,但是他此時(shí)調(diào)用的self是closure中的強(qiáng)引用self
所以有構(gòu)成循環(huán)引用
結(jié)論:
如果在closure引用了self.但是self不引用closure,此時(shí)不會(huì)發(fā)生循環(huán)引用
如果self還引用了closure,這個(gè)時(shí)候就需要[weak self] 或者 [unowned self] 去修飾
如果有多層的closure嵌套,要在最外層的closure中修飾self,否則會(huì)發(fā)生循環(huán)引用