1、定义一个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?
}
#### 然后添加方法进行测试:
-
1
func test() {
let closure: TestClosure = {
self.name = ""
}
closure()
}
不会循环引用
closure引用了name,但是 self 没有引用closure,
不构成互相强引用的关系
- ##### 2 ``` func test2() {
let closure: TestClosure = {
self.name = ""
}
closure()
self.closure = closure
}
> **会**
closure引用了name,self 也引用closure, 构成互相强引用的关系
<br>
- ##### 3
func test3() {
let closure: TestClosure = {[weak self] in
let closure1: TestClosure = {
self?.name = "dddd"
}
closure1()
}
closure()
self.closure = closure
}
> 不会
closure中使用了[weak self] 修饰,所以在整个closure中的self都是弱引用, 虽然在closure1中并没有用[weak self]关键字,但是他此时调用的self是closure中的弱引用self 所以没有构成循环引用
<br>
- ##### 4
func test4() {
let closure: TestClosure = {
let closure1: TestClosure = { [weak self] in
self?.name = "dddd"
}
closure1()
}
closure()
self.closure = closure
}
> 会
closure中并没有使用了[weak self] 修饰,所以在整个closure中的self都是强引用, 虽然在closure1中并有用[weak self]关键字,但是他此时调用的self是closure中的强引用self 所以有构成循环引用
<br>
####结论:
如果在`closure`引用了`self.`但是`self`不引用`closure`,此时不会发生循环引用
如果`self`还引用了`closure`,这个时候就需要`[weak self]` 或者 `[unowned self]` 去修饰
如果有多层的`closure`嵌套,要在最外层的`closure`中修饰`self`,否则会发生循环引用