【问题标题】:RxSwift withLatestFrom with resultSelector doesn't compileRxSwift withLatestFrom 和 resultSelector 无法编译
【发布时间】: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.Input 的hasItems 驱动程序上捕获一个事件,当我收到一个事件时,我需要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

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

【问题讨论】:

    标签: swift rx-swift rx-cocoa


    【解决方案1】:

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

    如果您想在 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 感谢您的解释!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-16
    • 1970-01-01
    • 2016-06-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多