RXSwift 闭包中的“[weak self]”
'[weak self]' in RXSwift closures
我需要在 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)
如果存在强引用循环,您将要使用 [unowned self]
或 [weak self]
。闭包内的变量可以被闭包 "owned" 并且如果闭包是,它会一直存在,所以这就是我们做 [unowned self]
或 [weak self]
.
的原因
如果闭包不属于 class 您不必使用 [weak self]
.
在 in-line 闭包的情况下,闭包不属于 class 而属于它所在的范围,并且将在离开范围时释放。
如果传入闭包,它可能属于也可能不属于 class(例如 属性),谨慎使用 [weak self]
以防它被拥有由 class.
是的,如果您在闭包中访问 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] 表示当 block 被调用时 self 不能为 nil called.if block 被调用并且 self 为 nil,然后应用程序崩溃。
[weak self] 意味着当块得到时 self 可以为 nil called.As 就此而言,你必须在块内处理可选的 self。
所以,我的快速回答是
1.when 您在视图控制器块中引用视图模型,请始终使用 [unowned self] 因为您可以确保视图模型始终存在于其关联的视图控制器中。
2.in 其他情况,当你在 block.choose unowned vs weak 中使用 self 时,总是会被提醒,这取决于 self 是否可以为 nil。
我需要在 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)
如果存在强引用循环,您将要使用 [unowned self]
或 [weak self]
。闭包内的变量可以被闭包 "owned" 并且如果闭包是,它会一直存在,所以这就是我们做 [unowned self]
或 [weak self]
.
如果闭包不属于 class 您不必使用 [weak self]
.
在 in-line 闭包的情况下,闭包不属于 class 而属于它所在的范围,并且将在离开范围时释放。
如果传入闭包,它可能属于也可能不属于 class(例如 属性),谨慎使用 [weak self]
以防它被拥有由 class.
是的,如果您在闭包中访问 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] 表示当 block 被调用时 self 不能为 nil called.if block 被调用并且 self 为 nil,然后应用程序崩溃。
[weak self] 意味着当块得到时 self 可以为 nil called.As 就此而言,你必须在块内处理可选的 self。
所以,我的快速回答是 1.when 您在视图控制器块中引用视图模型,请始终使用 [unowned self] 因为您可以确保视图模型始终存在于其关联的视图控制器中。
2.in 其他情况,当你在 block.choose unowned vs weak 中使用 self 时,总是会被提醒,这取决于 self 是否可以为 nil。