RxSwift map的意外nil值>订阅

时间:2018-05-17 21:38:21

标签: swift rx-swift

这只是一个样本。

但我能理解这种行为。为什么首先变量不是可选的,但在最后一个变量是可选的。

let tapEvent: ControlEvent<UITapGestureRecognizer> = chargingView.rx.tapGesture()
            tapEvent.map { _ in
                return CGPoint()
                }.filter { $0 != nil }.map { $0 } // here Comparing non-optional value of type 'CGPoint' to nil always returns true
                .subscribe { point in
                    print(point.element) // Expression implicitly coerced from 'CGPoint?' to Any
                }.disposed(by: bag)

要截取的屏幕截图。

enter image description here

此类似代码的行为相同

let tapEvent: ControlEvent<UITapGestureRecognizer> = chargingView.rx.tapGesture()
            tapEvent.map { _ in
                return CGPoint()
                }.flatMap { Observable.from(optional: $0) }
                .subscribe { point in
                    print(point.element)

我不熟悉rx。感谢。

2 个答案:

答案 0 :(得分:1)

让我们解决这个问题:

let pointArray = tapEvent.map { return CGPoint() }
let filteredArray = pointArray.filter { $0 != nil }
let newPointArray = filteredArray.map { $0 }
let subscribed = newPointArray.subscribe { point in
    print(point.element)
}
subscribed.disposed(by: bag)

这可能不是100%完美,但它足以澄清一些。

pointArray将是一个非可选的空CGPoint值数组。

由于它们不是可选的,因此删除nil值的过滤器毫无意义,是第一个错误的原因。只需删除filter

然后将filteredArray中的对象映射到自己。再次,这是毫无意义的。删除第二张地图。

第二个错误与point.element有关。我对RxSwift和基于警告的这个特定方法一无所知,闭包的point参数是可选的。您可能需要在?之前添加.

通过所有这些,您的代码变为:

let pointArray = tapEvent.map { return CGPoint() }
let subscribed = pointArray.subscribe { point in
    print(point?.element)
}
subscribed.disposed(by: bag)

或以原始格式书写:

let tapEvent: ControlEvent<UITapGestureRecognizer> = chargingView.rx.tapGesture()
tapEvent.map { return CGPoint() }
    .subscribe { point in
        print(point?.element)
    }.disposed(by: bag)

是否有意义执行剩余的map,我不知道。看起来很奇怪但又一次,我不知道RxSwift。

答案 1 :(得分:0)

在第一种情况下,过滤器运算符的输入参数是CGPoint非可选的。由于它是非可选项,因此无法将其与nil进行比较。

在第二种情况下.flatMap { Observable.from(optional: $0) }Observable<Observable<CGPoint>>展平为Observable<CGPoint>

在Swift中,它等同于:

let arrayOfArrays = [[1,2,3,4]]
let array = arrayOfArrays.flatMap{$0} //Output: [1,2,3,4]