Rx : Reactive eXtensions 리엑티브 프로그래밍 패러다임이고, 데이터 흐름과 그 데이터의 변경에 따라 전달 되는 것을 중요시 생각하는 패러다임 같습니다.
Rx는 Observable 흐름을 가지고, 비동기 프로그래밍을 하기 위한 API 입니다.관련 어려운 단어!
Reactive Programming (RP)
Functional + RX = Functional Reactive Programming(FRP)
Language-Intergrated Query (LINQ)
왜 이리 공부하기 힘들지?
ReactiveX
RxSwift 셈플링을 하며 기능 익히기를 위한 레파지토리입니다.
테스트 소스를 작성하면서 공부를 하고 있습니다.
아직은 미흡하죠 .. 계속 수정중
첫 화면 (계속 공부하며 수정 중) | 11. 구구단을 공부해 볼까요? |
---|---|
Rx
에겐 특별한 것이 있다.
- ** ☆ Rx에겐 특별한 것이 있다. ☆ ** : 특별합니다.!!
- 높은 가독성이 있습니다.
- 코드가 기존 방식에 비해 간결해 진다고 합니다.
- 유지보수에 좋습니다.
- 기획 변동에 유연하다고 합니다.
- 하나의 방식으로 비동기 처리를 합니다.
- NotificationCenter, Delegate, KVO, GCD .. 등.. Observable로 단일화 됩니다.
- 쉬운 비동기 코드
- 테스트 하기 좋습니다.
- 쉽게 사용할 수 있는 좋은 아키텍쳐들도 있습니다.
- 회사에 안드로이드, 프론트 모두 RX로 되어있다면, 모두가 RX로 대화할 수 있습니다. (러닝커브가 이해하면.. 높은 만큼 대화에 재미가 있습니다.)
- 러닝 커브가 높습니다.
- FRP의 구현체 : http://reactivex.io/
- 사용/활용법을 알아야죠? : http://www.rxmarbles.com/
- 필요한 오퍼레이터 들이 있고, 이해하기 좋게 조작해 볼 수 있습니다.
ClintJang
마기님
tilltue님
민소네님
Kanghoon님
어떻게 시작을 어떻게 해야될지 모르겠습니다. 어떤 라이브러리를 기본으로 가져가서 프로젝트를 생성하며, 그걸 기반으로 기본 UI를 해보고, 네트워크 활용을 해보면 기초적인 개념은 익힐 것 것 같아서 .. 이런 순서로 기본 기능들을 사용해 나가면 되지 않을 까 싶습니다.
아직은 적용한 셈플은 없음.
- RxAlamofire : Swift Alamofire를 RxSwift로 감싼 HTTP 네트워킹 라이브러리
ReactiveX에서 Observer는 Observable를 구독합니다. Observable이 배출하는 하나 또는 연속된 항목에 Observer는 반응합니다. Observable이라는 객체를 활용해서 내보내고, 관찰 및 구독해서 원하는 개발을 가능하게 하여주죠.👍
- 데이터 발행자 : 가장 핵심적인 개념이며, 이벤트를 시간의 흐름에 따라 전달하는 전달자 입니다.데이터의 변화가 발행하는 데이터 소스 입니다.
- 비동기적으로 다수의 이벤트를 다루는 방법입니다.
- 옵저버 패턴의 확장이라 생각하면 됩니다.
옵저버블
(데이터 발행자
)은 이벤트를옵저버
(데이터 수신자
)에 전달합니다.Hot Observable
,Cold Observable
가 있습니다.- 콜드 옵저버블 의 개념이 있습니다. : 누군가 자신을 구독해야 Lazy evaluation(느긋한 계산법)이 되서 이벤트를 발생시키는 개념
- 콜드 옵저버블은 구독(subscribe())하지 않으면 데이터를 발행하지 않습니다.
- 핫 옵저버블은 구독과 관계없이 데이터를 발행합니다.
해지 시키는 역활을 하죠.
- subscribe(구독하다)가 반환해 주는 것이 disposable(일회용)
- disposeBag 은 disposable 들을 담아두는 것을 말합니다.
- 만약 해지 하고 싶은 대상의 disposeBag에 담으면, 그 대상이 메모리 해지 될때(dealloc) 담겨있는 disposable이 해지됩니다.
- 해지가 안되면 메모리 릭이 발생하겠죠.
옵저버가 BehaviorSubject를 구독하기 시작하면, 옵저버는 소스 Observable이 가장 최근에 발행한 항목(또는 아직 아무 값도 발행되지 않았다면 맨 처음 값이나 기본 값)의 발행을 시작하며 그 이후 소스 Observable(들)에 의해 발행된 항목들을 계속 발행합니다.
Subject를 Wrapping 하고 있고, dispose 되기 전까지 계속 작동하는 특징이 있죠.
Variable=> BehaviorRelay
https://github.com/ClintJang/sample-rxswift-beginning/blob/master/README.md#creating-observables
-
.. (중략) .. Observable.just(1) .subscribe(onNext:{ print($0) }, onError: { print($0) }, onCompleted: {print("onCompleted")}) .disposed(by:disposeBag) Observable.just("안녕하세요.") .subscribe(onNext:{ print($0) }, onError:{ print($0) }, onCompleted:{ print("onCompleted")}) .disposed(by: disposeBag) Observable.just([1,2,3,4]) .subscribe(onNext:{ print($0) }, onError:{ print($0) }, onCompleted:{ print("onCompleted")}) .disposed(by: disposeBag) let service: Observable<Int> = Observable.just(99) service.subscribe(onNext:{ print($0) }, onError:{ print($0) }, onCompleted:{ print("onCompleted")}) .disposed(by: disposeBag) .. (중략) ..
-
.. (중략) .. Observable.from([1,2,3]) .subscribe(onNext:{ print($0) }, onError: { print($0) }, onCompleted: {print("onCompleted")}) .disposed(by:disposeBag) Observable.from(["기억","니은","디긋", "ㅎㅎㅎ"]) .subscribe(onNext:{ print($0) }, onError: { print($0) }, onCompleted: {print("onCompleted")}) .disposed(by:disposeBag) .. (중략) ..
-
.. (중략) .. Observable.range(start: 1, count: 4) .subscribe(onNext: { print("onNext::\($0)") }, onError: { print($0)}, onCompleted: { print("onCompleted") }) .disposed(by: disposeBag) .. (중략) ..
-
.. (중략) .. let deferred = Observable<String>.deferred { // just("defer")의 실행을 늦춰보자!! Observable<String>.just("defer").debug() } // 딜레이 시키고 싶은 시간을 정하자 let delayTime = 3.0 print("== \(delayTime) 초 뒤에 subscribe 를 실행 할 것이고") print("== 그때!! Observable<String>.just(..).debug() 가 실행 될 것입니다.") print("\n\n") // 3초 뒤에 "Observable<String>.just("defer").debug()" 실행 DispatchQueue.main.asyncAfter(deadline: .now() + delayTime) { [weak self] in if let strongSelf = self { deferred.subscribe(onNext:{ print($0) }) .disposed(by: strongSelf.disposeBag) } } .. (중략) ..
-
.. (중략) .. print("===============================") print("첫번째 Interval 실행") print("서브스크라이브 되서, 2초 후 부터 반복") print("\n\n") let intervalFirst = 2 // 2초에 한번씩 Observable<Int>.interval(RxTimeInterval(intervalFirst), scheduler: MainScheduler.instance) .subscribe({ print("첫번째:\($0)") }) .disposed(by: disposeBag) print("===============================") print("두번째 Interval 실행") print("서브스크라이브 되서, 3초 후 부터 반복, 5회만 반복") print("\n\n") let intervalSecond = 3 // 3초에 한번씩 Observable<Int>.interval(RxTimeInterval(intervalSecond), scheduler: MainScheduler.instance) .map({ $0 + 1000 }) // 1000, 1001, 1002... .take(5) // 5회 .subscribe({ print("두번째:\($0)") }) .disposed(by: disposeBag) print("===============================") print("\n\n") .. (중략) ..
-
.. (중략) .. print("===============================") print("첫번째 Timer 실행") print("서브스크라이브 되서, 2초 후 부터 실행") print("\n\n") let intervalFirst = 2 // 2초에 한번씩 Observable<Int>.timer(RxTimeInterval(intervalFirst), scheduler: MainScheduler.instance) // .debug() .subscribe({ print("첫번째:\($0)") }) .disposed(by: disposeBag) print("===============================") print("두번째 Timer 실행") print("서브스크라이브 되서, 3초 후 에 실행") print("\n\n") let intervalSecond = 3 // 3초에 한번씩 Observable<Int>.timer(RxTimeInterval(intervalSecond), scheduler: MainScheduler.instance) .map({ $0 + 1000 }) // 1000, 1001, 1002... .subscribe({ print("두번째:\($0)") }) .disposed(by: disposeBag) print("===============================") print("\n\n") .. (중략) ..
.. 아직
아직
아직
아직
-
.. (중략) .. let firstSequence: Observable<Int> = Observable.range(start: 1, count: 5) let secondSequence: Observable<Int> = Observable.from([6,7,8,9,10]) let thirdSequence: Observable<Int> = Observable.of(11, 12, 13, 14, 15) let _ = Observable.concat(firstSequence, secondSequence, thirdSequence) .subscribe( onNext: { print($0) }, onError: { print($0) }, onCompleted: { print("onCompleted") }) { print("onDisposed") } .disposed(by: disposeBag) .. (중략) ..
.. 계속 공부합시다.