关于 ios:Custom flatMapLatest with nil wrapping

Custom flatMapLatest with nil wrapping

我有一些测试函数可以观察值并将它们映射到另一个 Observable

1
2
3
4
5
6
7
8
private func test1() {
    selectedTagsVariable
        .asObservable()
        .flatMapLatest { [weak self] tags -> Observable<PostSet> in
            guard let strongSelf = self else { return .empty() }
            return strongSelf.postSetObservable(for: tags)
        }
}

没关系,但我不希望每次都检查自我价值为零。当然,我可以将weak替换为unowned,但不正确。

所以,我创建了自定义 flatMapLatest:

1
2
3
4
5
6
7
8
9
10
11
extension ObservableType {

func xflatMapLatest<A:AnyObject, O: ObservableType>(weak obj: A, selector: @escaping (A, Self.E) throws -> O) -> Observable<O.E> {
    return flatMapLatest { [weak obj] value -> Observable<O.E> in
        guard let strongObj = obj else {
            return Observable.empty()
        }
        return try selector(strongObj, value) as! Observable<O.E>
    }
}
}

它看起来像这样:

1
2
3
4
5
6
7
private func test2() {
    selectedTagsVariable
        .asObservable()
        .xflatMapLatest(weak: self) { obj, tags -> Observable<PostSet> in
            return obj.postSetObservable(for: tags)
        }
}

问题:我不喜欢 xflatMapLatest 函数中返回类型 (as! Observable<O.E>) 的类型转换。我可以以某种方式删除它吗?帮助重构这个方法:)


您想要的是通过简单的修改来镜像 flatMapLatest 运算符。看看它的签名:

1
func flatMapLatest<O : ObservableConvertibleType>(_ selector: @escaping (Self.E) throws -> O) -> RxSwift.Observable<O.E>

如你所见,selector闭包的结果类型必须符合ObservableConvertibleType,其定义如下:

1
2
3
4
public protocol ObservableConvertibleType {
    associatedtype E
    public func asObservable() -> RxSwift.Observable<Self.E>
}

知道了这一点,就很容易看出您需要做哪些小改动才能让它发挥作用:

1
2
3
4
5
6
7
8
9
10
extension ObservableType {
    func flatMapLatestWeak<A: AnyObject, O: ObservableConvertibleType>(weak obj: A, selector: @escaping (A, E) throws -> O) -> Observable<O.E> {
        return flatMapLatest { [weak obj] value -> Observable<O.E> in
            guard let strongObj = obj else {
                return Observable.empty()
            }
            return try selector(strongObj, value).asObservable()
        }
    }
}

此外,您可以使用 Optional<T>\\'s map:

缩短此方法

1
2
3
4
5
6
7
extension ObservableType {
    func flatMapLatestWeak<A: AnyObject, O: ObservableConvertibleType>(weak obj: A, selector: @escaping (A, E) throws -> O) -> Observable<O.E> {
        return flatMapLatest { [weak obj] value in
            try obj.map{ try selector($0 , value).asObservable() } ?? .empty()
        }
    }
}