弱引用直通主题不发送输入

Weak referenced Passthrough Subject doesn't send input

提问人:incelemeTRe 提问时间:7/2/2023 最后编辑:incelemeTRe 更新时间:7/2/2023 访问量:51

问:

我正在尝试一些模式,在某个时候我意识到我的直通对象在自我虚弱时不会发送任何东西。这是我所做的:

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)在使用前将其解开,它也无法正常工作?

iOS Swift 合并 弱引用 发布者

评论

0赞 Paulw11 7/2/2023
如何订阅发布者。显示该代码。
0赞 incelemeTRe 7/2/2023
我添加了订阅代码@Paulw11
1赞 matt 7/2/2023
相反,说 .不要使用var viewModel : ViewModel?!

答:

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、发布者、订阅、汇等无关。这只是弱意味着什么的问题。