Observable + Generic
이전 포스팅에서 Observable에 대해 알아보았다.
그 땐 Int 타입에 대해서만 다루었었는데 만약 String 값을 넣는다면 어떻게 될까?
당연히 타입이 맞지 않기 때문에 Observable은 사용이 불가해질 것이다.
그러면 다음과 같이 또 Observable을 만들어 주어야할까???
// In Observable
class Observable {
var listener: ( (String) -> Void)?
var value: String {
didSet {
listener?(value)
}
}
init(value: String) {
self.value = value
}
func bind(completionHandler: @escaping (String) -> Void) {
completionHandler(value)
listener = completionHandler
}
}
// In ViewController
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
var example = Observable(value: "김치찌개")
example.bind(completionHandler: { (menu) in
print("오늘점심은 \(menu)!!!")
})
example.value = "된장찌개"
example.value = "돈까스"
}
}
/*
오늘점심은 김치찌개!!!
오늘점심은 된장찌개!!!
오늘점심은 돈까스!!!
*/
만약 이런식으로 매 번 Observable을 만들어줘야 한다면 너무 비효율적일 것이다.
이 때 제네릭(Generic)을 사용한다면 여러 타입(String, Int, Double, Struct...) 등이 들어와도 문제없이 사용이 가능하다.
여기서 제네릭이란 간단하게 설명하자면 모든 타입을 아우를 수 있는 타입?이라고 보면된다.
보통 T로 사용되며 T의 자리엔 어떠한 타입이 들어와도 된다.
제네릭을 한 번 사용해 보자.
// In Observable
class Observable<T> {
var listener: ( (T) -> Void)?
var value: T {
didSet {
listener?(value)
}
}
init(value: T) {
self.value = value
}
func bind(completionHandler: @escaping (T) -> Void) {
completionHandler(value)
listener = completionHandler
}
}
// In ViewController
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
var example = Observable(value: [1, 2, 3, 4, 5])
example.bind(completionHandler: { (menu) in
print("오늘점심은 \(menu)!!!")
})
example.value = [66, 77, 88, 99]
example.value = [111, 222]
}
}
/*
오늘점심은 [1, 2, 3, 4, 5]!!!
오늘점심은 [11, 22, 33]!!!
오늘점심은 [555, 666]!!!
*/
우리가 살펴봐야할 것은 Observable<T>
, 타입으로 쓰인 T
그리고 ViewController에서 김치찌개, 된장찌개, 돈가스 대신 Int배열이 들어간 것이다.
우선 제네릭을 사용하니 Int배열이 들어가도 문제없이 잘 출력되는 것을 볼 수 있다.
그런데 <T>
와 T
가 사용부분이 제네릭에대한 이해가 없으면 조금 헷갈릴 수도? 있을텐데 너무 어렵게 생각할 필요없다.
Observable<T>
는 Observable 클래스에서 제네릭으로 T를 사용하겠다고 선언하는 것이다.
그리고 그냥 T
는 String, Int, Double, Struct 등등 타입이 들어올 수 있도록 하는 자리이다.
만약 Observable<A>
라고 했으면 제네릭으로 A를 사용하겠다는 의미이고 위의 T자리 대신 A가 들어가면 되는 것이다.
이렇게 우리는 제네릭을 사용하여 반복되게 Observable 클래스를 만들어 줄 필요가 없게되었다.
다음 포스팅에선 간단한 프로젝트를 MVVM패턴을 사용해보고 이를 사용해 반응형 프로그래밍에 대해 가볍게 살펴보자.