Just ask who else is there right now? 45 degrees up in the sky, damn it! My charm with no place to put it!

  • RxSwift (1) — Preliminary study
  • RxSwift (2) – Core logic source code analysis
  • RxSwift (3) – How the Observable sequence is created
  • RxSwift (4) — Higher Order functions (1)
  • RxSwift (5) — Higher Order functions (lower)
  • RxSwift (6) — Scheduler source scheduler
  • RxSwift (7) — Scheduler scheduler
  • RxSwift (8) — KVO Low-level Exploration (1)
  • RxSwift (9) — KVO Low-level Exploration (2)
  • RxSwift (10) — Summary of scene sequences
  • RxSwift (11) — Dispose source code parsing
  • RxSwift (12) — Subject is both offensive and defensive
  • RxSwift (13) — Climb over the pit
  • RxSwift (14) — MVVM bidirectional binding

RxSwift directory through train — Harmonious learning, not impatient!


Sequence is very important in the world of RxSwift, usually the development process with a good sequence to create, can give development to bring twice the result with half the effort! This chapter summarizes common ways to create sequences

1: emty

Start with an empty sequence – the sequence event is an Int, so the emTY call has no sequence, only complete

print("********emty********")
let emtyOb = Observable<Int>.empty()
_ = emtyOb.subscribe(onNext: { (number) in
    print("Subscribe.",number)
}, onError: { (error) in
    print("error:",error)
}, onCompleted: {
    print("Complete callback") {})print("Release callback")}Copy the code
  • It’s not very common, but let’s do it in terms of points and surfaces
  • View through source code analysis
override func subscribe<O: ObserverType>(_ observer: O) -> Disposable where O.E= =Element {
    observer.on(.completed)
    return Disposables.create()
}
Copy the code
  • Obviously when you subscribe, directlyobserver.on(.completed)It sends a done signal, very neat

2: just

  • Single signal sequence created
  • This method is initialized by passing in a default value to build a single elementObservableQueue, subscribe to the message automaticallycomplete.
  • The following example is explicitly labeledObservableThe type ofObservable<[String]>, that is, this is specifiedObservableThe data type carried by the emitted event must beType Stringthe
print("********just********")
//MARK: just
// Create a single signal sequence
let array = ["LG_Cooci"."LG_Kody"]
Observable"[String]>.just(array)
    .subscribe { (event) in
        print(event)
    }.disposed(by: disposeBag)

_ = Observable"[String]>.just(array).subscribe(onNext: { (number) in
    print("Subscribe.",number)
}, onError: { (error) in
    print("error:",error)
}, onCompleted: {
    print("Complete callback") {})print("Release callback")}Copy the code
  • It feels like a little bit of data convenience
  • This sequence in peacetime development or application inside a lot of, look at the underlying source code
override func subscribe<O: ObserverType>(_ observer: O) -> Disposable where O.E= =Element {
    observer.on(.next(self._element))
    observer.on(.completed)
    return Disposables.create()
}
Copy the code
  • observer.on(.next(self._element))It will be sent after regular subscriptions.nextThe event
  • And then it automatically sends the completion event, exactly as we did

3: of

  • This method creates a new observable instance with a variable number of elements.
  • This method can accept a variable number of arguments (which must be of the same type)
print("********of********")
//MARK: of
// Multiple elements - for sequence processing
Observable<String>.of("LG_Cooci"."LG_Kody")
    .subscribe { (event) in
        print(event)
    }.disposed(by: disposeBag)

/ / a dictionary
Observable"[String: Any]>.of(["name":"LG_Cooci"."age":18])
    .subscribe { (event) in
        print(event)
    }.disposed(by: disposeBag)

/ / array
Observable"[String]>.of(["LG_Cooci"."LG_Kody"])
    .subscribe { (event) in
        print(event)
    }.disposed(by: disposeBag)
Copy the code
  • No matterThe dictionary.An array of.Multiple elementsAll in normal use
  • The structure of the underlying source code is also well-behaved
  • Initialization saves the scheduling environment and the elements passed in
  • The subscription process is also leveragedsinkAnd then throughmutableIteratorIterators handle sending

4: the from

  • Convert an optional sequence to an observable sequence.
  • Get sequences from collections: Array, collection,set get sequences – with optional handling – more secure
print("********from********")
// MARK: from
Observable"[String]>.from(optional: ["LG_Cooci"."LG_Kody"])
    .subscribe { (event) in
        print(event)
    }.disposed(by: disposeBag)
Copy the code
  • self._optional = optionalLow-level initialization is optional to save
  • The subscription process determines if it matches our options
  • sendobserver.on(.next(element))The sequence * is then automaticobserver.on(.completed)Complete sequence sending

5: deferred

  • Returns an observable sequence that calls the specified factory function when a new observer subscribes.
  • There is one requirement: dynamic sequence-based on external identifiers – dynamic output
  • usedeferred()Method to delayObservables sequenceInitialization through the incomingblockTo implement theObservables sequenceClass and return.
print("********defer********")
//MARK: defer
var isOdd = true
_ = Observable<Int>.deferred { () -> Observable<Int> in
    // Design our sequence hereisOdd = ! isOddif isOdd {
        return Observable.of(1.3.5.7.9)}return Observable.of(0.2.4.6.8)
    }
    .subscribe { (event) in
        print(event)
    }
Copy the code
  • self._observableFactory = observableFactoryInitialization saves this section of the factory closure
func run() -> Disposable {
    do {
        let result = try self._observableFactory()
        return result.subscribe(self)
    }
    catch let e {
        self.forwardOn(.error(e))
        self.dispose()
        return Disposables.create()
    }
}
Copy the code
  • In the subscription process tosinkWhen this section of factory closure is executed
  • It feels like the middle layer is being packaged

6: reaching

  • Generates and sends observer messages using the specified scheduler to generate a sequence of observable integers within the specified range.
print("********rang********")
//MARK: rang
Observable.range(start: 2.count: 5)
    .subscribe { (event) in
        print(event)
    }.disposed(by: disposeBag)

// Underlying source code
init(start: E.count: E, scheduler: ImmediateSchedulerType) {
    self._start = start
    self._count = count
    self._scheduler = scheduler
}

override func run<O : ObserverType>(_ observer: O, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where O.E= =E {
    let sink = RangeSink(parent: self, observer: observer, cancel: cancel)
    let subscription = sink.run()
    return (sink: sink, subscription: subscription)
}
Copy the code
  • Saves the value of the first integer in the sequence.
  • Saves the number of sequential integers to be generated.
  • Save the scheduling environment
if i < self._parent._count {
    self.forwardOn(.next(self._parent._start + i))
    recurse(i + 1)}else {
    self.forwardOn(.completed)
    self.dispose()
}
Copy the code
  • Based on previously saved information, the state of the data also climbs and then recurses to the specified requirements

7: the generate

  • An observable sequence is generated by running a state-driven loop that produces sequence elements, running the loop using the specified scheduler to send observer messages.
  • This method creates a value only if all of the supplied criteria aretrue“, will give the actionObservableSequence.
  • Given the initial value and thenJudgment Condition 1Judgment Condition 2Will always beRecursive downUntil theCondition 1 or condition 2 is not met
  • Similar to array traversal loop
  • – parametersinitialState: Indicates the initial state.
  • Parameter 2 –condition: Terminates the build condition (when “false” is returned).
  • Three – parameteriterate: iterative step function.
  • – Parameter quad scheduler: scheduler used to run generator loops. Default:CurrentThreadScheduler.instance.
  • – Returns: generated sequence.
print("********generate********")
//MARK: generate
Observable.generate(initialState: 0./ / initial value
                    condition: { $0 < 10}, 1 / / conditions
                    iterate: { $0 + 2 })  // Condition 2 +2
    .subscribe { (event) in
        print(event)
    }.disposed(by: disposeBag)

// Array traversal
let arr = ["LG_Cooci_1"."LG_Cooci_2"."LG_Cooci_3"."LG_Cooci_4"."LG_Cooci_5"."LG_Cooci_6"."LG_Cooci_7"."LG_Cooci_8"."LG_Cooci_9"."LG_Cooci_10"]
Observable.generate(initialState: 0./ / initial value
    condition: { $0 < arr.count}, 1 / / conditions
    iterate: { $0 + 1 })  // Condition 2 +2
    .subscribe(onNext: {
        print("Traverse arr.",arr[$0])
    })
    .disposed(by: disposeBag)
Copy the code

8: the timer

  • Returns an observable sequence that uses the specified scheduler to run a timer that periodically generates a value after the specified initial relative expiration time.
  • First parameter: the time from the first response to the present
  • Second parameter: time interval
  • Third parameter: thread
print("********timer********")
//MARK: timer
Observable<Int>.timer(5, period: 2, scheduler: MainScheduler.instance)
    .subscribe { (event) in
        print(event)
    }
.disposed(by: disposeBag)

// Set a time limit for a specified period
Observable<Int>.timer(1, scheduler: MainScheduler.instance)
    .subscribe { (event) in
        print("111111111 \(event)")}//.disposed(by: disposeBag)
Copy the code
  • The status code keeps climbing and the interval time keeps sending responses

9: the interval

  • Returns an observable sequence that generates a value after each cycle to run the timer and send observer messages using the specified scheduler.
print("********interval********")
//MARK: interval
/ / timer
Observable<Int>.interval(1, scheduler: MainScheduler.instance)
    .subscribe { (event) in
        print(event)
    }
    //.disposed(by: disposeBag)
Copy the code

9: repeatElement

  • Sends an observer message using the specified scheduler, generating an observable sequence that repeats the given element indefinitely.
print("********repeatElement********")
//MARK: repeatElement
Observable<Int>.repeatElement(5)
    .subscribe { (event) in
        // print(" subscribe :",event)
    }
    .disposed(by: disposeBag)
Copy the code

10: the error

  • Returns an observable sequence ending with “error”.
  • This sequence is usually more common in development, request network failure will also send a failure signal!
print("********error********")
//MARK: error
// Send a wrong signal to consumers
Observable<String>.error(NSError.init(domain: "lgerror", code: 10086, userInfo: ["reason":"unknow"]))
    .subscribe { (event) in
        print("Subscribe.",event)
    }
    .disposed(by: disposeBag)
Copy the code

11: never

  • The method creates a never issuedEventIt won’t stopObservableSequence.
  • This type of response source is useful when testing or disabling the exact source in the composite operator
print("********never********")
//MARK: never
Observable<String>.never()
    .subscribe { (event) in
        print("Leave you",event)
    }
    .disposed(by: disposeBag)
print("********never********") 
Copy the code

12: the create ()

  • This method takes a parameter in the form of a closure, and its job is to process each incoming subscription.
  • Here is a simple example. Subscription code has been added for demonstration purposes
  • This is also a common way to create sequences, and there are a lot of applications
let observable = Observable<String>.create{observer in
    // A.next event was issued to the subscriber, carrying a data "hangge.com"
    observer.onNext("hangge.com")
    // A.completed event was issued to the subscriber
    observer.onCompleted()
    Since a subscription has a Disposable return value, we must returen a Disposable at the end
    return Disposables.create()
}
 
// Subscribe tests
observable.subscribe {
    print($0)}Copy the code

Sequence creation is also the foundation of learning RxSwift, there are a lot of times I encountered a lot of bugs, to put it bluntly is the foundation did not master! Now we have finished the tenth lesson of RxSwift, many students have a more in-depth understanding of RxSwift, of course, here I still write in the form of blog, is hoping that you can come back in time to have a look, I know, there will be a lot of students back to continue to deepen the foundation!

Just ask who else is there right now? 45 degrees up in the sky, damn it! My charm with no place to put it!