提问人:incelemeTRe 提问时间:7/2/2023 最后编辑:incelemeTRe 更新时间:7/2/2023 访问量:51
弱引用直通主题不发送输入
Weak referenced Passthrough Subject doesn't send input
问:
我正在尝试一些模式,在某个时候我意识到我的直通对象在自我虚弱时不会发送任何东西。这是我所做的:
import Foundation
import Combine
class ViewModel {
var publisher = PassthroughSubject<[WebData], Never>()
let apis : [ApiProtocol]
init(apis: [ApiProtocol]){
self.apis = apis
getData()
}
func getData(){
guard !apis.isEmpty else { return }
apis.forEach {api in
api.getApiData { [weak self] webData in
self?.publisher.send(webData)
}
}
}
}
由于我宣布[弱我]并写下
self?.publisher.send(webData)
我没有从视图控制器中的接收器闭合处接收任何数据。但是如果我删除 [弱自我] 并调用具有强自我的 send 方法:
func getData(){
guard !apis.isEmpty else { return }
apis.forEach {api in
api.getApiData { webData in
self.publisher.send(webData)
}
}
}
它发送数据,视图控制器完美地接收它。但是现在,它不是导致了保留周期吗?为什么它在自我声明为弱数据时不发送数据?我在这里错过了什么?
编辑:以下是我如何使用水槽封口:
class DataVC: UIViewController {
weak var viewModel : ViewModel?
var models = [WebData]()
var cancellable = [AnyCancellable]()
@IBOutlet weak var tableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
downloadData()
tableView.delegate = self
tableView.dataSource = self
}
func downloadData() {
guard let model = viewModel else { return }
model.publisher
.receive(on: DispatchQueue.main)
.sink { _ in
} receiveValue: { [weak self] value in
self?.models.append(contentsOf: value)
DispatchQueue.main.async {
self?.tableView.reloadData()
}
}.store(in: &cancellable)
}
}
DataVC 表视图 protovol 确认在扩展中。它们工作得很好,所以我没有在这里添加它们。
编辑2:现在,我将视图控制器中 viewModel 的声明从:
weak var viewModel : ViewModel?
对不弱者:
var viewModel : ViewModel!
...它一开始就与弱引用发布者一起工作。好的,这解决了我的问题。但是,为什么当 viewModel 很弱时,即使我(guard-let)在使用前将其解开,它也无法正常工作?
答:
1赞
matt
7/2/2023
#1
为什么当 viewModel 很弱时,即使我(guard-let)在使用前将其解开,它也无法正常工作?
因为弱就是弱!
weak var viewModel : ViewModel?
这意味着“不保留 viewModel”。其他任何内容也不会保留 ViewModel 对象,因此它会在您可以使用它之前立即消失。到你说的时候
guard let model = viewModel
viewModel
走了,变成了零,我们只是回来了。
评论
1赞
matt
7/2/2023
与 Combine、发布者、订阅、汇等无关。这只是弱意味着什么的问题。
评论
var viewModel : ViewModel?
!