Skip to content

Commit

Permalink
Merge pull request #13 from splendo/feature/fix-observable-freezing
Browse files Browse the repository at this point in the history
force main thread for Observable, Subject and LivecycleViewModel
  • Loading branch information
vpodlesnyak authored Feb 2, 2022
2 parents 581b8a4 + 051d83a commit 2aa465c
Show file tree
Hide file tree
Showing 7 changed files with 35 additions and 7 deletions.
6 changes: 5 additions & 1 deletion stencils/LifecycleViewModel.stencil
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,16 @@ class LifecycleViewModel<VM: BaseViewModel> {
let containerView: ContainerView?

init(_ viewModel: VM, containerView: ContainerView? = nil) {
assert(Thread.isMainThread, "Constructor must be called on the main thread, but called on \(Thread.current)")
self.viewModel = viewModel
self.containerView = containerView
}

deinit {
viewModel.clear()
let vm = viewModel
DispatchQueue.main.async {
vm.clear()
}
}

func lifecycleView<V: View>(view: (VM) -> V) -> some View {
Expand Down
6 changes: 5 additions & 1 deletion stencils/ListObservable.stencil
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ class ListObservable<Output: Equatable>: ObservableObject {
animated: Bool = false,
mapper: @escaping (NSArray) -> [Output] = ListMapper.to
) {
assert(Thread.isMainThread, "Constructor must be called on the main thread, but called on \(Thread.current)")
input = observable.currentOrNull
if input != nil {
value = mapper(input!)
Expand Down Expand Up @@ -48,7 +49,10 @@ class ListObservable<Output: Equatable>: ObservableObject {
}

deinit {
disposeBag.dispose()
let bag = disposeBag
DispatchQueue.main.async {
bag.dispose()
}
}
}

Expand Down
6 changes: 5 additions & 1 deletion stencils/ListSubject.stencil
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ class ListSubject<Output: Equatable>: ObservableObject {
animated: Bool = false,
mapper: @escaping (NSArray) -> [Output] = ListMapper.to
) {
assert(Thread.isMainThread, "Constructor must be called on the main thread, but called on \(Thread.current)")
input = subject.currentOrNull
if input != nil {
value = mapper(input!)
Expand Down Expand Up @@ -54,7 +55,10 @@ class ListSubject<Output: Equatable>: ObservableObject {
}

deinit {
disposeBag.dispose()
let bag = disposeBag
DispatchQueue.main.async {
bag.dispose()
}
}
}

Expand Down
6 changes: 5 additions & 1 deletion stencils/Observable.stencil
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ class Observable<Input: KotlinObject, Output: Equatable>: ObservableObject {
animated: Bool = false,
mapper: @escaping (Input) -> Output
) {
assert(Thread.isMainThread, "Constructor must be called on the main thread, but called on \(Thread.current)")
input = observable.currentOrNull
if input != nil {
value = mapper(input!)
Expand Down Expand Up @@ -59,7 +60,10 @@ class Observable<Input: KotlinObject, Output: Equatable>: ObservableObject {
}

deinit {
disposeBag.dispose()
let bag = disposeBag
DispatchQueue.main.async {
bag.dispose()
}
}
}

Expand Down
6 changes: 5 additions & 1 deletion stencils/Subject.stencil
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ class Subject<Input: KotlinObject, Output: Equatable>: ObservableObject {
toMapper: @escaping (Input) -> Output,
fromMapper: @escaping (Output) -> Input
) {
assert(Thread.isMainThread, "Constructor must be called on the main thread, but called on \(Thread.current)")
input = subject.currentOrNull
if input != nil {
value = toMapper(input!)
Expand Down Expand Up @@ -61,7 +62,10 @@ class Subject<Input: KotlinObject, Output: Equatable>: ObservableObject {
}

deinit {
disposeBag.dispose()
let bag = disposeBag
DispatchQueue.main.async {
bag.dispose()
}
}
}

Expand Down
6 changes: 5 additions & 1 deletion stencils/UninitializedObservable.stencil
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ class UninitializedObservable<Input: KotlinObject, Output: Equatable>: Observabl
animated: Bool = false,
mapper: @escaping (Input?) -> Output?
) {
assert(Thread.isMainThread, "Constructor must be called on the main thread, but called on \(Thread.current)")
input = observable.currentOrNull
if input != nil {
value = mapper(input!)
Expand Down Expand Up @@ -53,7 +54,10 @@ class UninitializedObservable<Input: KotlinObject, Output: Equatable>: Observabl
}

deinit {
disposeBag.dispose()
let bag = disposeBag
DispatchQueue.main.async {
bag.dispose()
}
}
}

Expand Down
6 changes: 5 additions & 1 deletion stencils/UninitializedSubject.stencil
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ class UninitializedSubject<Input: KotlinObject, Output: Equatable>: ObservableOb
toMapper: @escaping (Input?) -> Output?,
fromMapper: @escaping (Output?) -> Input?
) {
assert(Thread.isMainThread, "Constructor must be called on the main thread, but called on \(Thread.current)")
input = subject.currentOrNull
if input != nil {
value = toMapper(input!)
Expand Down Expand Up @@ -65,7 +66,10 @@ class UninitializedSubject<Input: KotlinObject, Output: Equatable>: ObservableOb
}

deinit {
disposeBag.dispose()
let bag = disposeBag
DispatchQueue.main.async {
bag.dispose()
}
}
}

Expand Down

0 comments on commit 2aa465c

Please sign in to comment.