' [弱自我]'在RXSwift关闭

时间:2016-01-25 22:07:50

标签: swift closures rx-swift

我是否需要在RXSwift subscribeNext闭包中使用[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)

4 个答案:

答案 0 :(得分:15)

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

在内联闭包的情况下,闭包不是由类所拥有,而是由它所在的范围所有,并且在放置范围时将被释放。

如果传递闭包,它可能也可能不属于该类(例如属性),并且谨慎使用integral,因为它属于该类。

答案 1 :(得分:14)

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

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

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

请参阅示例中的DetailViewController

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

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

答案 2 :(得分:0)

如果有强大的参考周期,您会想要使用[unowned self][weak self]。闭包内部的变量可以由闭包“拥有”,并且如果闭合的话,它会粘在一起,这就是我们[unowned self][weak self]的原因。

答案 3 :(得分:0)

[unown self]表示调用block时self不能为零。如果调用block且self为nil,则应用崩溃。

[weak self]表示调用块时self可以为nil。因此,您必须在块内部处理可选self。

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

2。在其他情况下,如果您在一个区块中使用self,则始终会收到警报。根据self是否可以为nil来选择无主vs弱。