https://usinuniverse.bitbucket.io/blog/rxswiftmvvmpart1.html 를 개인적으로 정리한 글입니다.
MVVM
- Model, View, View Model의 약자
View
- View와 애니메이션
ViewModel
- 비즈니스 로직과 API 호출
- Model과 상호작용하여 View에서 필요한 데이터를 가지고 있지만, 직접 건네주는 것이 아님
-> View에서 바인딩을 통해 ViewModel에게서 필요한 데이터를 가져가야 함
- View Model은 View에 대해 아무것도 몰라야 하며 UIKit을 import해서도 안됨
RxSwift
- View와 ViewModel을 바인딩하기 위한 효과적 도구
- Reactive Programming에 기반을 두고 있음
Reactive Programming이란
(1) 기존의 프로그래밍
var a = 3
var b = 7
var c = a+b // 10
a = 1
print(c) //10
(2) Reactive Programming
var a = 3
var b = 7
var c = a+b // 10
a = 1
print(c) //8
값이 변경된 a에 대해 자동으로 c가 변경된 것을 볼 수 있음
-> 변화에 반응하여 자동으로 변경된다는 것이 Reactive Programming의 핵심
Reactive Programming에서는 모든것이 스트림이며 UI이벤트나 네트워크 요청도 역시 스트림
스트림이란?
- 버튼을 누르면 특정 문자열을 출력하는 함수가 있다는 함수가 있다고 가정
- 버튼을 누르는 순간부터, 출력을 완료하는 과정 자체가 하나의 스트림
실생활의 예시
- 우리는 항상 휴대폰(Observable : 관찰가능한) 을 예의주시하고 있음
- 전화가 오는지, 카톡이 오는지 항상 신경씀 : SubScribe(구독하다)
-> 우리는 필요에 따라 관찰가능한 휴대폰을 구독하고 있다가 휴대폰이 방출하는 이벤트에 반응
RxSwift의 기초
Observable과 Subscriber
- Observable과 Observers(혹은 Subscribers)가 존재
- ObservableType protocol을 준수한다면 어떤 것도 Observable이 될 수 있음
(1) Observable 생성
let observableString = Observable.just("Hello, RxSwift")
let observableInt = Observable.of(0,1,2)
let observableDict = Observable.from([1: "Hello", 2:"RxSwift"])
- just, of, from 등은 Observable 생성 연산자
(2) Observable 구독
let observableString = Observable.just("Hello, RxSwift")
observableString.subscribe{ print($0) }
//next(Hello, Rxswift)
//completed
- 왜 그냥 "Hello, RxSwift" 출력이 아니라 next, completed가 붙을까?
-> Rx세계에서는 모든것이 스트림이기 때문
※ Marble Diagram
- 3개의 Observable
첫 번째 Observable : 1부터 6까지의 int형의 데이터가 6번 방출된 후 종료
두 번째 Observable : String형의 값인 a~f까지 방출하다 에러
세 번째 Observable : 세번의 tap 이벤트 발생
- 해석
가로선 : 시간의 흐름, 하나의 스트림
| : 하나의 스트림 종료 시점
X : 에러를 나타냄, 스트림 종료 시점
(3) next, completed, error
Rx 하에서는 스트림이 next, completed, error 3가지 종류의 이벤트로 구성
- Observable이 구독자에게 방출할 값이 있다면 next 이벤트를 통해 방출
-> 더 이상 방출할 값이 없다면 마지막으로 completed 이벤트 방출 후 종료
-> 중간에 error가 발생한다면 error 이벤트를 방출 후 종료
var observableInt = Observable.of(1,2,3,4,5,6)
observableInt.subscribe{ print($0) }
//next(1)
//next(2)
//next(3)
//next(4)
//next(5)
//next(6)
//completed
(4) Dispose : Observable 구독 취소
Observable을 구독할 수 있듯 구독을 취소할 수도 있음
이것을 Dispose라 부르며, Rx에서는 DisposeBag에 담아 구독 취소
-> 순환참조로 인한 메모리 누수를 피하기 위함
let disposeBag = DisposeBag()
var observableInt = Observable.of(1,2,3,4,5,6)
observableInt.
subscribe { print($0) }
.disposed(by: disposedBag)
- ViewController에서 메모리가 해제될 때 disposeBag에 담긴 메모리에서 같이 해제
- 만약 중간에 해제하길 원한다면 disposeBag을 초기화하면 됨
※ RxSwift 코드 예제
Int형을 방출하는 Observable을 구독하고 있다가 2의 배수인 경우에만 10을 곱해서 출력하는 예제코드
let disposeBag = DisposeBag()
var observableInt = Observable.of(1,2,3,4,5,6,7,8)
observableInt
.filter { $0.isMultiple(of:2) } //2의 배수만 filter
.map { $0 * 10 } //10 곱하기
.subscribe { print($0) } //방출되는 값들이 출력
.disposed(by: disposeBag) //모든 값이 방출되면 구독을 취소
//next(20)
//next(40)
//next(60)
//next(80)
//completed
'iOS' 카테고리의 다른 글
[스탠포드iOS] Swift 기초문법 정리(Method, Property) (0) | 2024.03.16 |
---|---|
[스탠포드iOS] Swift 기초문법 정리(Optional, Tuple, Data Structure) (1) | 2024.03.16 |
RxSwift(2) - 연산 (0) | 2020.04.04 |
RxSwift(1) (0) | 2020.04.03 |