Swift中closure的循环引用记录

2019-04-27  本文已影响0人  Codepgq

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?
}



然后添加方法进行测试:

func test() {
        
        let closure: TestClosure = {
            self.name = ""
        }
        
        closure()
    }

不会循环引用

 closure引用了name,但是 self 没有引用closure,
 不构成互相强引用的关系
    func test2() {
        
        let closure: TestClosure = {
            self.name = ""
        }
        
        closure()
        self.closure = closure
    }

closure引用了name,self 也引用closure,
构成互相强引用的关系
    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
所以没有构成循环引用
    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
所以有构成循环引用

结论:

如果在closure引用了self.但是self不引用closure,此时不会发生循环引用
如果self还引用了closure,这个时候就需要[weak self] 或者 [unowned self] 去修饰
如果有多层的closure嵌套,要在最外层的closure中修饰self,否则会发生循环引用

上一篇 下一篇

猜你喜欢

热点阅读