RXSwift 闭合中的'[weak self]'



我需要在RXSwift订阅中使用[weak self]吗?

我有代码:

    searchController.searchBar.rx_text.throttle(0.2, scheduler: MainScheduler.instance).subscribeNext { searchText in
        self.viewModel.searchForLocation(searchText)
    }.addDisposableTo(DisposelBag.sharedDisposelBag.disposeBag)

我是否需要修改它,以便在关闭开始时有一个[weak self]捕获列表?喜欢这个:

    searchController.searchBar.rx_text.throttle(0.2, scheduler: MainScheduler.instance).subscribeNext { [weak self] searchText in
        self?.viewModel.searchForLocation(searchText)
    }.addDisposableTo(DisposelBag.sharedDisposelBag.disposeBag)

如果闭包不属于该类,则不必使用 [weak self]

在内联闭包的情况下,闭包不属于类,而归它所在的范围所有,当作用域离开时将被释放。

如果传入闭包,则它可能归类(例如属性)所有,也可能不归类所有,如果它由类拥有,则谨慎使用[weak self]

是的,如果您在闭包中访问self,您应该创建self的弱捕获,并且self可能会在调用闭包之前变得nil

如果闭包捕获了self,然后self变得nil,则当调用闭包并尝试访问该self时,您将获得异常。

感谢scotteg,他在GitHub上有一个示例项目:https://github.com/scotteg/TestRxSwiftClosures

请参阅示例中的DetailViewController

您可以取消注释其他两个示例(一次一个)以查看结果。第一个根本不定义捕获列表,第二个定义unowned捕获。运行应用并输入一些文本,然后点击 5 秒内完成(每次关闭有 5 秒的延迟)。前两个示例将导致引发异常。

基本规则是这样的:如果捕获(例如,self)可以设置为 nil ,例如如果它引用的实例被解除分配,则将捕获定义为 weak 。否则,如果闭包和该闭包中的捕获将始终相互引用并同时解除分配,请将捕获定义为 unowned

如果

存在强大的参考循环,您将需要使用[unowned self][weak self]。闭包中的变量可以被闭包"拥有",如果闭包是,就会保留下来,所以这就是我们做[unowned self][weak self]的原因。

[unowned self] 表示当块被调用时,self 不能为零。如果块被调用并且 self 为 nil,则应用程序崩溃。

[弱自我]意味着当块被调用时,自我可以为零。因此,您必须在块内处理可选的自我。

所以,我的快速回答是1.当您在视图控制器块中引用视图模型时,请始终使用 [unowned self],因为您可以确保视图模型始终存在于其关联的视图控制器中。

2.in 其他情况下,当您在块中使用 self 时,请务必收到警报。根据 self 是否可以为零来选择无主与弱。

最新更新