Swift之循环引用

Swift中的循环引用是怎么样的呢?我们来看看:

 func loadData(completion:@escaping ()->()) -> () {
   
    //异步
    DispatchQueue.global().async { 
        print("耗时操作")
        
        DispatchQueue.main.async {
           //回调,执行闭包
            completion()
        }
    }
}

//类似于oc的dealloc
deinit {
    print("我去了")
}

调用:

loadData {
        print(self.view)
    }

这样是不会引起循环引用的,为什么呢?

//block中如果出现self.要特别小心
//循环引用单方向对引用是不会产生循环引用
//只是闭包对self.进行了copy,闭包执行完成之后,会自动销毁,同时释放对self引用

要循环引用还要self对闭包引用:
所以循环引用是下面这样的:

func loadData(completion:@escaping ()->()) -> () {
   
    //使用属性记录闭包 -> self对闭包引用了
    completionCallBack = completion
    
    //异步
    DispatchQueue.global().async { 
        print("耗时操作")
        Thread.sleep(forTimeInterval: 2.0)
        
        DispatchQueue.main.async {
           //回调,执行闭包
            completion()
        }
    }
}

//类似于oc的dealloc
deinit {
    print("我去了")
}

调用:

class ViewController: UIViewController {
//属性就是一个var
var completionCallBack: (()->())?


override func viewDidLoad() {
    super.viewDidLoad()
   
         print(self.view)
    }

这样就形成了循环引用,我们可以在sb中加个nav测试一下,deinit就不会打印。
循环引用就是一个环, 我引用你,你引用我,所以就会形成循环引用,要解除循环引用,就需要打断链条,有三种方法,第一种是用OC的方式如下:

//方法一:用OC的方式
    //细节一 var weak只能修饰var 不能修饰let
    //'weak' must be a mutable variable, because it may change at runtime
    //weak可能会被在运行时被修改 -> 指向的对象被释放会被自动设置为nil
    weak var weakSelf = self;
    loadData {
        //细节二 
        //解包有两种方式解包
        //? 可选解包 -如果self已经被释放,不会向对象发送getter的消息,更加安全
        //!强行解包 -如果self已经被释放,强行解包会导致崩溃
        
        /**
         weakSelf?.view  只是单纯的发送消息,没有计算
         强行解包 因为需要计算 可选项不能直接参与到计算
        */
        print(weakSelf?.view as Any)

    }

方法二,使用swift推荐的方法:

//方法二:swfit的推荐方法
    //[weak self]表示{}中的所有self都是弱引用,需要注意解包
    loadData { [weak self] in
        print(self?.view as Any)
    }

方法三:

//方法三:swfit的另外一个方法 知道就好
    //[unowned self]表示{}中的所有slef都是assign的,不会强引用,但是。如果释放,指针地址不会变化
    //如果对象被释放,继续调用就会出现野指针的问题
    loadData { [unowned self] in
        print(self.view as Any)
    }

循环引用的解决办法推荐使用第一种和第二种方法。

你可能感兴趣的:(Swift之循环引用)