带有 nil 包装的自定义 flatMapLatest
Custom flatMapLatest with nil wrapping
我有一些测试函数,观察者对其进行赋值并将其映射到另一个 Observable
:
private func test1() {
selectedTagsVariable
.asObservable()
.flatMapLatest { [weak self] tags -> Observable<PostSet> in
guard let strongSelf = self else { return .empty() }
return strongSelf.postSetObservable(for: tags)
}
}
没关系,但我不想每次都检查 self 值为 nil。当然,我可以把weak
换成unowned
,但是不对。
所以,我创建了自定义 flatMapLatest
:
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>
}
}
}
看起来像这样:
private func test2() {
selectedTagsVariable
.asObservable()
.xflatMapLatest(weak: self) { obj, tags -> Observable<PostSet> in
return obj.postSetObservable(for: tags)
}
}
问题:我不喜欢 return 类型 (as! Observable<O.E>
) 中 xflatMapLatest
函数的类型转换。我可以以某种方式删除它吗?帮助重构这个方法:)
您想要的是通过简单的修改来镜像 flatMapLatest
运算符。看看它的签名:
func flatMapLatest<O : ObservableConvertibleType>(_ selector: @escaping (Self.E) throws -> O) -> RxSwift.Observable<O.E>
如您所见,selector
闭包的结果类型必须符合 ObservableConvertibleType
,其定义如下:
public protocol ObservableConvertibleType {
associatedtype E
public func asObservable() -> RxSwift.Observable<Self.E>
}
知道了这一点,就很容易看出您需要做哪些小的改变才能让它发挥作用:
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>
的 map
:
来缩短此方法
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([=13=] , value).asObservable() } ?? .empty()
}
}
}
我有一些测试函数,观察者对其进行赋值并将其映射到另一个 Observable
:
private func test1() {
selectedTagsVariable
.asObservable()
.flatMapLatest { [weak self] tags -> Observable<PostSet> in
guard let strongSelf = self else { return .empty() }
return strongSelf.postSetObservable(for: tags)
}
}
没关系,但我不想每次都检查 self 值为 nil。当然,我可以把weak
换成unowned
,但是不对。
所以,我创建了自定义 flatMapLatest
:
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>
}
}
}
看起来像这样:
private func test2() {
selectedTagsVariable
.asObservable()
.xflatMapLatest(weak: self) { obj, tags -> Observable<PostSet> in
return obj.postSetObservable(for: tags)
}
}
问题:我不喜欢 return 类型 (as! Observable<O.E>
) 中 xflatMapLatest
函数的类型转换。我可以以某种方式删除它吗?帮助重构这个方法:)
您想要的是通过简单的修改来镜像 flatMapLatest
运算符。看看它的签名:
func flatMapLatest<O : ObservableConvertibleType>(_ selector: @escaping (Self.E) throws -> O) -> RxSwift.Observable<O.E>
如您所见,selector
闭包的结果类型必须符合 ObservableConvertibleType
,其定义如下:
public protocol ObservableConvertibleType {
associatedtype E
public func asObservable() -> RxSwift.Observable<Self.E>
}
知道了这一点,就很容易看出您需要做哪些小的改变才能让它发挥作用:
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>
的 map
:
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([=13=] , value).asObservable() } ?? .empty()
}
}
}