import Foundation
import RxSwift
print("Hello, World!")
var status = true
var disposeBag = DisposeBag()
Observable.just(3)
.observeOn(ConcurrentDispatchQueueScheduler(qos: .default))
.subscribe(onNext:{ int in
sleep(UInt32(int))
status = false
}
).disposed(by: disposeBag)
print("Event 1!")
disposeBag = DisposeBag() // Cancel Operation
while status{
}
print("Event 2!")
print(status)
위 코드를 실행시키면 아래의 결과가 나옵니다.
Hello, World!
Event 1!
Event 2!
false
Program ended with exit code: 0
왜 이런 결과가 나오는지 모르겠습니다. disposeBag = DisposeBag()를 실행시키면 onNext의 작업이 취소되는 걸로 압니다. 그러므로 3초가 되기 전에 취소가 되므로 status는 false가 되지 못하므로
while문에서 status는 평생 true가 되기 때문에 무한 loop에 걸려야 하는 것 아닌가요?
왜 Event 1!이 출력된 후에 정확히 3초 후에 Event 2!라는 문구와 false가 나오면서 정상적으로 실행되는지 여쭤보고 싶습니다.
미리 감사합니다.
subscribe 된 후에 while문이 일어난듯 하네요.
Observable이 시작할 때 init으로 disposeBag를 초기화 시키던가, 비동기적으로 deadline을 설정해줄 수 있지 않을까요?
혹시 sleep이 언제 걸린 것인지 알 수 있을까요?
잠깐 찾아보니 https://magi82.github.io/ios-rxswift-03/
let disposable = Observable.interval(1, scheduler: MainScheduler.instance)
.take(10)
.subscribe(onNext: { value in
print(value)
}, onError: { error in
print(error)
}, onCompleted: {
print("onCompleted")
}, onDisposed: {
print("onDisposed")
})
DispatchQueue.main.asyncAfter(deadline: .now() + 3) {
disposable.dispose()
}
이렇게 사용하면 중단시킬수 있나보네요.
disposeBag = DisposeBag() 는 실행구문이 아닙니다...
이미 disposeBag 인스턴스에 다시 새로운 DisposeBag 인스턴스를 할당하면서 먼저 들어 있던 Observer 가 메모리에서 해제되는 것 뿐...
어떤게 궁금해서 저렇게 코드를 작성하셨는지는 모르겠으나, sleep()은 프로세스 전체를 중지하는 거라 그냥 코드가 순서대로 실행됩니다.(sleep() 때문에 순서대로 실행되는 것은 아닙니다.)
Subscribed가 먼저 찍힐 때도 있고, Disposed가 먼저 찍힐 때도 있고, 그러네요. 일단 Subscribed가 찍히기만 하면 onNext 블록이 시작된 것이라서, 그 이후 Disposed가 되든 말든 3초 후에 status = false 구문은 실행됩니다.
메인 큐의 dispose하는 이벤트와 백그라운드 큐의 onNext 실행시키는 이벤트가 동시(Concurrently)에 진행되다 보니 실행할 때마다 어떤 게 먼저 발생하는지가 다르고, 그에 따라 무한 루프에 걸릴지 말지 달라지는 듯합니다. 백그라운드 큐의 우선순위가 높아질수록 onNext가 발생할 확률이 높네요.