44

我需要[weak self]在 RXSwift subscribeNext 闭包中使用吗?

我有代码:

    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

4 回答 4

23

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

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

如果传入了闭包,它可能属于也可能不属于类(例如属性),并且在它[weak self]由类拥有的情况下使用它是谨慎的。

于 2016-01-25T23:35:15.783 回答
20

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

如果一个闭包捕获self然后self变成nil,当调用闭包并尝试访问它self时,您将得到一个异常。

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

请参阅DetailViewController示例中的。

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

基本规则是:如果捕获(例如self)可以设置为nil,例如如果它引用的实例被释放,则将捕获定义为weak。否则,如果闭包和闭包内的捕获将始终相互引用并同时被释放,则将捕获定义为unowned.

于 2016-03-19T23:15:50.887 回答
2

你会想要使用[unowned self]或者[weak self]是否会有一个强大的参考周期。闭包内的变量可以由闭包“拥有”,如果闭包是,它们会一直存在,所以这就是我们这样做的原因[unowned self]or [weak self]

于 2016-01-25T22:24:12.327 回答
1

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

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

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

2.在其他情况下,当你在一个块中使用 self 时总是被提醒。根据 self 是否可以为 nil 来选择 unowned 和 weak。

于 2020-05-31T06:51:42.073 回答