Add withUnretained for SharedSequence (Driver, Signal)

This commit is contained in:
freak4pc 2021-01-01 13:42:50 +02:00
parent 000c0e6727
commit e3f3401d80
8 changed files with 115 additions and 3 deletions

View File

@ -242,6 +242,7 @@ custom_categories:
- Using
- Window
- WithLatestFrom
- WithUnretained
- Zip+Collection
- Zip+arity
- Zip

View File

@ -443,6 +443,37 @@ extension SharedSequence {
}
}
// MARK: - withUnretained
extension SharedSequenceConvertibleType {
/**
Provides an unretained, safe to use (i.e. not implicitly unwrapped), reference to an object along with the events emitted by the sequence.
In the case the provided object cannot be retained successfully, the seqeunce will complete.
- parameter obj: The object to provide an unretained reference on.
- parameter resultSelector: A function to combine the unretained referenced on `obj` and the value of the observable sequence.
- returns: An observable sequence that contains the result of `resultSelector` being called with an unretained reference on `obj` and the values of the original sequence.
*/
public func withUnretained<Object: AnyObject, Out>(
_ obj: Object,
resultSelector: @escaping (Object, Element) -> Out
) -> SharedSequence<SharingStrategy, Out> {
SharedSequence(self.asObservable().withUnretained(obj, resultSelector: resultSelector))
}
/**
Provides an unretained, safe to use (i.e. not implicitly unwrapped), reference to an object along with the events emitted by the sequence.
In the case the provided object cannot be retained successfully, the seqeunce will complete.
- parameter obj: The object to provide an unretained reference on.
- returns: An observable sequence of tuples that contains both an unretained reference on `obj` and the values of the original sequence.
*/
public func withUnretained<Object: AnyObject>(_ obj: Object) -> SharedSequence<SharingStrategy, (Object, Element)> {
withUnretained(obj) { ($0, $1) }
}
}
// MARK: withLatestFrom
extension SharedSequenceConvertibleType {

View File

@ -18,12 +18,12 @@ extension ObservableType {
*/
public func withUnretained<Object: AnyObject, Out>(
_ obj: Object,
resultSelector: @escaping ((Object, Element)) -> Out
resultSelector: @escaping (Object, Element) -> Out
) -> Observable<Out> {
map { [weak obj] element -> Out in
guard let obj = obj else { throw UnretainedError.failedRetaining }
return resultSelector((obj, element))
return resultSelector(obj, element)
}
.catch{ error -> Observable<Out> in
guard let unretainedError = error as? UnretainedError,
@ -35,6 +35,7 @@ extension ObservableType {
}
}
/**
Provides an unretained, safe to use (i.e. not implicitly unwrapped), reference to an object along with the events emitted by the sequence.

View File

@ -644,3 +644,64 @@ extension InfallibleType {
Infallible(asObservable().share(replay: replay, scope: scope))
}
}
// MARK: - withUnretained
extension InfallibleType {
/**
Provides an unretained, safe to use (i.e. not implicitly unwrapped), reference to an object along with the events emitted by the sequence.
In the case the provided object cannot be retained successfully, the seqeunce will complete.
- parameter obj: The object to provide an unretained reference on.
- parameter resultSelector: A function to combine the unretained referenced on `obj` and the value of the observable sequence.
- returns: An observable sequence that contains the result of `resultSelector` being called with an unretained reference on `obj` and the values of the original sequence.
*/
public func withUnretained<Object: AnyObject, Out>(
_ obj: Object,
resultSelector: @escaping (Object, Element) -> Out
) -> Infallible<Out> {
Infallible(self.asObservable().withUnretained(obj, resultSelector: resultSelector))
}
/**
Provides an unretained, safe to use (i.e. not implicitly unwrapped), reference to an object along with the events emitted by the sequence.
In the case the provided object cannot be retained successfully, the seqeunce will complete.
- parameter obj: The object to provide an unretained reference on.
- returns: An observable sequence of tuples that contains both an unretained reference on `obj` and the values of the original sequence.
*/
public func withUnretained<Object: AnyObject>(_ obj: Object) -> Infallible<(Object, Element)> {
withUnretained(obj) { ($0, $1) }
}
}
extension InfallibleType {
// MARK: - withLatestFrom
/**
Merges two observable sequences into one observable sequence by combining each element from self with the latest element from the second source, if any.
- seealso: [combineLatest operator on reactivex.io](http://reactivex.io/documentation/operators/combinelatest.html)
- note: Elements emitted by self before the second source has emitted any values will be omitted.
- parameter second: Second observable source.
- parameter resultSelector: Function to invoke for each element from the self combined with the latest element from the second source, if any.
- returns: An observable sequence containing the result of combining each element of the self with the latest element from the second source, if any, using the specified result selector function.
*/
public func withLatestFrom<Source: InfallibleType, ResultType>(_ second: Source, resultSelector: @escaping (Element, Source.Element) throws -> ResultType) -> Infallible<ResultType> {
Infallible(self.asObservable().withLatestFrom(second.asObservable(), resultSelector: resultSelector))
}
/**
Merges two observable sequences into one observable sequence by using latest element from the second sequence every time when `self` emits an element.
- seealso: [combineLatest operator on reactivex.io](http://reactivex.io/documentation/operators/combinelatest.html)
- note: Elements emitted by self before the second source has emitted any values will be omitted.
- parameter second: Second observable source.
- returns: An observable sequence containing the result of combining each element of the self with the latest element from the second source, if any, using the specified result selector function.
*/
public func withLatestFrom<Source: InfallibleType>(_ second: Source) -> Infallible<Source.Element> {
withLatestFrom(second) { $1 }
}
}

View File

@ -0,0 +1 @@
../../Tests/RxSwiftTests/Observable+WithUnretainedTests.swift

View File

@ -2146,6 +2146,21 @@ final class VirtualSchedulerTest_ : VirtualSchedulerTest, RxTestCase {
("testVirtualScheduler_stress", VirtualSchedulerTest.testVirtualScheduler_stress),
] }
}
final class WithUnretainedTests_ : WithUnretainedTests, RxTestCase {
#if os(macOS)
required override init() {
super.init()
}
#endif
static var allTests: [(String, (WithUnretainedTests_) -> () -> Void)] { return [
("testObjectAttached", WithUnretainedTests.testObjectAttached),
("testObjectDeallocates", WithUnretainedTests.testObjectDeallocates),
("testObjectDeallocatesSequenceCompletes", WithUnretainedTests.testObjectDeallocatesSequenceCompletes),
("testResultsSelector", WithUnretainedTests.testResultsSelector),
] }
}
#if os(macOS) || os(iOS) || os(tvOS) || os(watchOS)
func testCase<T: RxTestCase>(_ tests: [(String, (T) -> () -> Void)]) -> () -> Void {
@ -2262,5 +2277,6 @@ func XCTMain(_ tests: [() -> Void]) {
testCase(SignalTests_.allTests),
testCase(SingleTest_.allTests),
testCase(VirtualSchedulerTest_.allTests),
testCase(WithUnretainedTests_.allTests),
])
//}

View File

@ -0,0 +1 @@
../../RxSwift/Observables/WithUnretained.swift

View File

@ -1,6 +1,6 @@
//
// Observable+WithUnretainedTests.swift
// RxSwift
// Tests
//
// Created by Vincent Pradeilles on 01/01/2021.
// Copyright © 2021 Krunoslav Zaher. All rights reserved.