create

๐Ÿ—๏ธ Observable.create โ€” ์ปค์Šคํ…€ ์‹œํ€€์Šค๋ฅผ ์ง์ ‘ ์„ค๊ณ„ํ•˜๊ธฐ

โ€œObservable์„ DIY ํ•˜์ž!โ€ ์ˆ˜๋งŽ์€ ํŒฉํ† ๋ฆฌ ๋ฉ”์„œ๋“œ๋กœ๋„ ๋ถ€์กฑํ•  ๋•Œ, create๋ฅผ ์‚ฌ์šฉํ•ด ์ž„์˜์˜ ๋ฐฉ์‹์œผ๋กœ onNext/onCompleted/onError๋ฅผ ์ œ์–ดํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.


1๏ธโƒฃ ์‹œ๊ทธ๋‹ˆ์ฒ˜ & ๊ธฐ๋ณธ ๊ตฌ์กฐ

Observable<Element>.create { observer -> Disposable in
    // 1. ์ด๋ฒคํŠธ ๋ฐฉ์ถœ
    observer.onNext(...)
    observer.onCompleted() // ๋˜๋Š” onError

    // 2. ์ •๋ฆฌ(ํ•ด์ œ) ๋กœ์ง ๋ฐ˜ํ™˜
    return Disposables.create {
        // cancel task, invalidate timer, deallocate resource
    }
}
  • observer: AnyObserver<Element> โ€” .onNext, .onError, .onCompleted ํ˜ธ์ถœ ๊ฐ€๋Šฅ.

  • Disposable: ๊ตฌ๋…์ด dispose ๋  ๋•Œ ํ˜ธ์ถœ๋  ์ •๋ฆฌ ํด๋กœ์ €.


2๏ธโƒฃ ์˜ˆ์ œ โ€” Alamofire ์—†๋Š” ๊ฐ„๋‹จ HTTP GET

func getRequest(url: URL) -> Observable<Data> {
    return Observable.create { observer in
        let task = URLSession.shared.dataTask(with: url) { data, _, error in
            if let err = error {
                observer.onError(err)
            } else if let d = data {
                observer.onNext(d)
                observer.onCompleted()
            }
        }
        task.resume()

        return Disposables.create {
            task.cancel() // dispose ์‹œ network cancel
        }
    }
}
  • ๊ตฌ๋…์ž์—๊ฒŒ๋Š” Cold Observable(๋งค ๊ตฌ๋…๋งˆ๋‹ค ์ƒˆ ์š”์ฒญ)๋กœ ๋™์ž‘.


3๏ธโƒฃ ์ฃผ์˜์‚ฌํ•ญ ์ฒดํฌ๋ฆฌ์ŠคํŠธ

์ฒดํฌ
์„ค๋ช…

โœ… observer ์ด๋ฒคํŠธ ์ˆœ์„œ

onNext* โ†’ onCompleted/onError ๋‹จ 1ํšŒ

โœ… ์Šค๋ ˆ๋“œ

ํ˜ธ์ถœ ์Šค๋ ˆ๋“œ๋ฅผ ๋ช…์‹œํ•˜๊ฑฐ๋‚˜ subscribeOn ํ™œ์šฉ

โœ… Dispose ์ฒ˜๋ฆฌ

๋น„๋™๊ธฐ ์ž‘์—… cancel / ํƒ€์ด๋จธ invalidate

โŒ retain cycle

observer ํด๋กœ์ € ๋‚ด๋ถ€ [weak self] ํ•„์š” ์‹œ


4๏ธโƒฃ Single.create ยท Maybe.create

  • Single: ์„ฑ๊ณต/์‹คํŒจ ๋‘˜ ์ค‘ ํ•˜๋‚˜๋งŒ ๋ฐฉ์ถœ (SingleEvent.success, .failure).

  • Maybe: ์„ฑ๊ณต(๊ฐ’)/์™„๋ฃŒ(๊ฐ’ ์—†์Œ)/์‹คํŒจ ์„ธ ๊ฐ€์ง€.

Single<String>.create { single in
    fetch(id: 1) { result in
        switch result {
        case .success(let str):
            single(.success(str))
        case .failure(let err):
            single(.failure(err))
        }
    }
    return Disposables.create()
}

5๏ธโƒฃ Mini Quiz

  1. Observable.create ๋‚ด๋ถ€์—์„œ .onNext๋ฅผ ๋‘ ๋ฒˆ ์—ฐ์† ํ˜ธ์ถœ ํ›„ .onCompleted() ์—†์ด ํ•จ์ˆ˜๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋ฉด ๋ฌด์Šจ ์ผ์ด ์ผ์–ด๋‚ ๊นŒ?

  2. ๋ทฐ์ปจํŠธ๋กค๋Ÿฌ deinit ์ „์— ๋„คํŠธ์›Œํฌ ์š”์ฒญ์„ ์ทจ์†Œํ•˜๋ ค๋ฉด ๋ฐ˜ํ™˜ Disposable์— ์–ด๋–ค ์ฝ”๋“œ๋ฅผ ๋„ฃ์–ด์•ผ ํ• ๊นŒ?

  3. Single.create์™€ AsyncSubject๋ฅผ ๋น„๊ตํ–ˆ์„ ๋•Œ ์ฐจ์ด์ ์€?

Answers
  1. ์ŠคํŠธ๋ฆผ์ด ์™„๋ฃŒ๋˜์ง€ ์•Š์•„ ๊ตฌ๋…์ž๊ฐ€ .completed ์ด๋ฒคํŠธ๋ฅผ ์ˆ˜์‹ ํ•˜์ง€ ๋ชปํ•˜๊ณ , ์ž‘์—…์ด ์˜๊ตฌํžˆ ์—ด๋ ค ์žˆ์„ ์ˆ˜ ์žˆ๋‹ค. (Dispose ํ˜ธ์ถœ ์‹œ๊นŒ์ง€ ์œ ์ถœ)

  2. task.cancel() ๊ณผ ๊ฐ™์ด URLSessionTask๋ฅผ ์ทจ์†Œํ•˜๊ฑฐ๋‚˜, alamofireRequest.cancel() ํ˜ธ์ถœ ๋“ฑ์„ ๋„ฃ์–ด Dispose ์‹œ ๋„คํŠธ์›Œํฌ ์ข…๋ฃŒ.

  3. Single์€ Cold์ด๊ณ  subscribe ์‹œ ์ƒ์„ฑยท๋ฐฉ์ถœยท์™„๋ฃŒ๋ฅผ ์Šค์Šค๋กœ ์ฒ˜๋ฆฌํ•˜์ง€๋งŒ, AsyncSubject๋Š” Hot์œผ๋กœ ์™ธ๋ถ€์—์„œ onNext/onCompleted ์ œ์–ดํ•œ๋‹ค.


๋‹ค์Œ โ–ถ๏ธ just, of, from ๋กœ ์ด๋™ํ•ด ์†์‰ฌ์šด ์‹œํ€€์Šค ํŒฉํ† ๋ฆฌ ๋ฉ”์„œ๋“œ just, of, from์„ ํ•™์Šตํ•ฉ๋‹ˆ๋‹ค. ๐Ÿš€

Last updated