RxSwift学习-15-RxSwift循环引用问题

492 阅读2分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第18天,点击查看活动详情

  • 本文主要介绍下RxSwift中的循环引用问题。

1. 闭包的循环引用

再讨论RxSwift中的内存管理,我们先回顾下Swift中闭包的循环引用问题

var myClousre:(()->())?

    var name: String?

    override func viewDidLoad() {

        super.viewDidLoad()

        

        print("来了")

        self.myClousre = {

            

            self.name = "jack"

        }

        // Do any additional setup after loading the view.

    }

我们push到子页面,定义一个闭包。在闭包中设置当前控制器的属性name。 捕获了对象,并修改了控制器的name的值但是没有执行deInit,此时self是全局变量没有释放. image.png

此时就是self->myClousre->self,造成了循环引用。

  • 解决 我们可以使用若引用或者无主引用打破循环

弱引用weak

image.png

无主引用unowned

image.png

无主引用unowned表示的你明确当前闭包和持有者的生命周期是一致的,比如我们当前的控制器和闭包是相互统一的生命周期。weak修饰的话则是不确定它们的生命周期是否一致,所以会有一个可选值?闭包修饰持有者。

关于Swift中内存管理可以看下之前我的文章swfit进阶-06-内存管理

2. RxSwift中的循环引用

我们使用RxSwift再序列中的闭包调用自身属性

var name: String?

    let disposeBag = DisposeBag()

    

    var ob: Observable<Int>?

    override func viewDidLoad() {

        super.viewDidLoad()

        print("来了")

        print(RxSwift.Resources.total)

        self.ob = Observable<Int>.create({ observer in

            self.name = "jack"

            return Disposables.create()

        })

        self.ob?.subscribe(onNext: { _ in

            print(self.name! as Any)

        }).disposed(by: disposeBag)

        print(RxSwift.Resources.total)

其中RxSwift.Resources.total是 计算内部Rx资源分配(可观察对象、观察对象、一次性物品等)。这提供了一种在开发期间检测泄漏的简单方法。
打印结果:

image.png 我们使用弱引用和无主引用的时候打破循环

image.png

对于我们RxSwift同样具有循环引用问题,也需要进行弱引用或无主引用打破循环。