首页 > 解决方案 > 使用组合转发对象

问题描述

为了更新视图,我想通过转发将视图从 ViewController 转发到 ViewModel。

类似于以下内容:

viewModel.labelViewModel.subscribe(forward: labelView) { labelView, model in labelView.update(with: model) }

但使用组合。

那么我怎样才能用 observable 返回观察者呢?

在 ViewController 我正在尝试:

viewModel.$labelModel.sink { lab in
    print("Value: \(lab?.1.text)")            
}.store(in: &subscriptions)

使用 ViewModel 中的标签:

@Published private(set) var labelModel: (Label, Label.Model)?

但我想要做的实际上是在接收器中返回与从 ViewController 订阅相同的标签。

这可能吗?

标签: swiftcombine

解决方案


你可以这样做:

extension Publisher {
    func withUnretained<Object: AnyObject>(_ obj: Object) -> AnyPublisher<(Object, Output), Error> {
        return tryMap { [weak obj] element -> (Object, Output) in
            guard let obj = obj else { throw UnretainedError.failedRetaining }
            return (obj, element)
        }
        .eraseToAnyPublisher()
    }
}

enum UnretainedError: Swift.Error {
    case failedRetaining
}

这将允许您执行以下操作:

$labelModel
    .withUnretained(label)
    .sink { (completion) in
        if case .failure = completion {
            print("oops!")
        }
    } receiveValue: { (label, text) in
        label.text = text
    }
    .store(in: &subscriptions)

但是,当您可以做到这一点时,为什么还要这样做呢?

$labelModel
    .sink { [label] text in
        label?.text = text
    }
    .store(in: &subscriptions)

推荐阅读