2019-10-12[unowned self] 与 [weak self]的区别

参考文章:Swift - RxSwift的使用详解42([unowned self] 与 [weak self])

最近学习RxSwift 无意间看到这篇文章,让我想起了之前调试代码时出现的bug。

仔细对比下面二者,我们可以发现:

        textField.rx.text.orEmpty.asDriver().drive(onNext: {
            [weak self] text in
            DispatchQueue.main.asyncAfter(deadline: .now() + 4) {
                print("当前输入内容:\(String(describing: text))")
                self?.label.text = text
            }
             
        }).disposed(by: disposeBag)
       textField.rx.text.orEmpty.asDriver().drive(onNext: {
            [unowned self] text in
            DispatchQueue.main.asyncAfter(deadline: .now() + 4) {
                print("当前输入内容:\(String(describing: text))")
                self.label.text = text
            }
             
        }).disposed(by: disposeBag)

作者如此区分:

我们只需将闭包捕获列表定义为弱引用(weak)、或者无主引用(unowned)即可解决问题,这二者的使用场景分别如下:

如果捕获(比如 self)可以被设置为 nil,也就是说它可能在闭包前被销毁,那么就要将捕获定义为 weak。
如果它们一直是相互引用,即同时销毁的,那么就可以将捕获定义为 unowned。

这样其实有点难理解:
weak 弱引用,允许被引用对象提前释放,即变成nil ,而代码中问号可选操作,巧妙避免崩溃。

unowned 表示不主动引用,实际上本质含义是:被引用对象的引用计数不会加一!!!
那么unowned 引用的对象也是可以被提前释放。我们如何规避呢?
在block中添加如下代码即可

guard let unownedSelf = self else {
  return 
}
unownedSelf.label.text = text

在代码修改过程中我也的确这样做了,但是崩溃问题并没有得到解决。原因是另一个问题了(原因是在deinit方法中:最好不要调用懒加载方法来创建新的变量,因为创建方法会引用self,会导致self对象内部结构发生变化,在deinit释放方法执行过程中,self是要被释放掉的,苹果是不可以在这个时候对self对象内部结构进行新的创建工作的。这个原因与本文主题无关,纯属作者自己随性添加)

你可能感兴趣的:(2019-10-12[unowned self] 与 [weak self]的区别)