RxSwift withLatestFrom 和 resultSelector 无法编译

Posted

技术标签:

【中文标题】RxSwift withLatestFrom 和 resultSelector 无法编译【英文标题】:RxSwift withLatestFrom with resultSelector doesn't compile 【发布时间】:2019-05-10 07:20:12 【问题描述】:

我有一个Bool 类型的Driver 和一个Page 类型的BehaviorRelay(这是一个自定义枚举)。

enum Page 
    case option1(CustomClass1, CustomClass2)
    case option2(CustomClass3)
    case option3(CustomClass4)

    var property1: CustomClass2? 
        switch self 
        case .option1(_, let custom):
            return custom
        case .option2, .option3:
            return nil
        
    

我在另一个 ViewModel 中有 Driver<Bool>

class ViewModel1 
    struct Output 
        let hasItems: Driver<Bool>
    

    let output: Output

    init() 
        let hasItemsRelay: BehaviorRelay<Bool> = BehaviorRelay<Bool>(value: false)

        self.output = Output(
            hasItems: hasItemsRelay.asDriver()
        )
    

我的基类中有一个BehaviorRelay&lt;Page?&gt;

class ViewModel2 
    let currentPageRelay: BehaviorRelay<Page?> = BehaviorRelay<Page?>(value: nil)

    init() 
        self.currentPageRelay = BehaviorRelay<Page?>(value: nil)
    

ViewModel2 类中,我试图在ViewModel1.InputhasItems 驱动程序上捕获一个事件,当我收到一个事件时,我需要currentPageRelay 的当前值,然后用它做一些事情。所以基本上withLatestFrom 是我需要使用的东西。

class ViewModel2 

   private func test() 
       let customViewModel: ViewModel1 = ViewModel1()

       customViewModel
           .output
           .hasItems
           .withLatestFrom(currentPageRelay)  ($0, $1) 
           .map  (hasItems, page) -> (CustomClass2, Bool)? in 
               guard let property1 = page?.property1 else  return nil 
               return (property1, hasItems)
           
           .unwrap()
           .drive(onNext:  (property1, hasItems) in 
               // do stuff
           
           .disposed(by: disposeBag)
   

Xcode 在withLatestFrom 上完全失去了它。没有代码完成,它给出了以下编译错误: Expression type '(Bool, _)' is ambiguous without more context

我对这个完全一无所知。我已经尝试了所有方法,在它下面的参数列表中提供了正确的类,以便它知道会发生什么等,但到目前为止还没有运气。

【问题讨论】:

【参考方案1】:

我认为因为.withLatestFrom 要求它所操作的两种类型具有相同的可观察特征。所以两者都应该是ObservableDriverSignal等。

如果您想在 viewModel 中保留 Driver Driver,您可以在 .hasItems 之后添加 .asObservable()

class ViewModel2 
    let currentPageRelay: BehaviorRelay<Page?> = BehaviorRelay<Page?>(value: nil)
    let disposeBag = DisposeBag()

    init() 
        // self.currentPageRelay = BehaviorRelay<Page?>(value: nil)
    

    private func test() 
        let customViewModel: ViewModel1 = ViewModel1()

        customViewModel
            .output
            .hasItems
            .asObservable()
            .withLatestFrom(currentPageRelay)  ($0, $1) 
            .map  (hasItems, page) -> (CustomClass2, Bool)? in
                guard let property1 = page?.property1 else  return nil 
                return (property1, hasItems)
            
            .asDriver(onErrorJustReturn: nil)
            .drive(onNext: 
                guard let (property1, hasItems) = $0 else 
                    return
                
                // do stuff
            )
            .disposed(by: disposeBag)
    


或者在withLatestFrom(..)中添加.asDriver()currentPageRelay

customViewModel
    .output
    .hasItems
    .withLatestFrom(currentPageRelay.asDriver())  ($0, $1) 
    .map  (hasItems, page) -> (CustomClass2, Bool)? in
        guard let property1 = page?.property1 else  return nil 
        return (property1, hasItems)
    
    .drive(onNext: 
        guard let (property1, hasItems) = $0 else 
            return
        
        // do stuff
    )
    .disposed(by: disposeBag)

【讨论】:

我现在遇到了这个问题并用谷歌搜索它,登陆这个页面并且就像,好吧!它准确地描述了我的问题是什么!然后我意识到这是我去年的帖子:facepalm。有谁知道为什么它不编译?谢谢你的回答顺便说一句。我只是超级好奇为什么它不能编译。 哈哈,我也经常遇到这种情况??‍♂️。我已经添加了一些说明,这有帮助吗? Owwww,现在我明白了:D 感谢您的解释!

以上是关于RxSwift withLatestFrom 和 resultSelector 无法编译的主要内容,如果未能解决你的问题,请参考以下文章

为啥 withLatestFrom 不返回最新值?

如何从 rxjs 6 withLatestFrom 键入数组映射参数

将参数传递给 withLatestFrom 函数

[RxJS] Combination operator: withLatestFrom

为啥我使用有效的 withLatestFrom 操作从选择器获取具有动作观察者属性的对象?

RxJs操作符,其行为类似于withLatestFrom,但会等待第二个流的值。