Reputation: 3355
When run in Debug scheme, there is a fatal error in line 30, if you code are something like this.
https://github.com/ReactiveX/RxSwift/blob/master/RxSwift/Observables/Implementations/Sink.swift
rxFatalError("Warning: Recursive call or synchronization error!")
If I choose run scheme from Debug to Release. The fatal error won't show. But I wonder if I could do something to suppress it.
class ViewController4: UIViewController {
var v = Variable(0)
var disposeBag = DisposeBag()
var notiBag = DisposeBag()
override func viewDidLoad() {
super.viewDidLoad()
v.asObservable()
.subscribe(onNext: { _ in
let noti = Notification(name: MyNotificationName)
NotificationCenter.default.post(noti)
})
.disposed(by: disposeBag)
NotificationCenter.default.rx.notification(MyNotificationName)
.subscribe(onNext: { [unowned self] _ in
if self.v.value == 10 { self.notiBag = DisposeBag() }
else { self.v.value += 1 } // this line cause the issue
print(self.v.value)
self.counterTextView.text! += "\(self.v.value)\n"
})
.disposed(by: notiBag)
v.value = 0
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
@IBOutlet weak var counterTextView: UITextView!
}
let MyNotificationName = Notification.Name.init(rawValue: "My Notification Name")
Upvotes: 1
Views: 1108
Reputation: 33967
You can have the same behavior without using the Variable
.
let scheduler = SerialDispatchQueueScheduler(qos: .userInitiated)
NotificationCenter.default.rx.notification(MyNotificationName)
.take(9)
.observeOn(scheduler)
.subscribe(onNext: { _ in
let noti = Notification(name: MyNotificationName)
print("foo")
NotificationCenter.default.post(noti)
}).disposed(by: bag)
let noti = Notification(name: MyNotificationName)
NotificationCenter.default.post(noti)
Upvotes: 1
Reputation: 3355
I have mark @thierryb 's answer as the correct one. The known correct answers are as below.
NotificationCenter.default.rx.notification(MyNotificationName)
.observeOn(MainScheduler.asyncInstance)
.subscribe(onNext: { [unowned self] _ in
if self.v.value == 10 { self.notiBag = DisposeBag() }
else { self.v.value += 1 } // this line cause the issue
print(self.v.value)
self.counterTextView.text! += "\(self.v.value)\n"
})
.disposed(by: notiBag)
or
NotificationCenter.default.rx.notification(MyNotificationName)
.subscribe(onNext: { [unowned self] _ in
DispatchQueue.main.async { [unowned self] in
if self.v.value == 10 { self.notiBag = DisposeBag() }
else { self.v.value += 1 } // this line cause the issue
print(self.v.value)
self.counterTextView.text! += "\(self.v.value)\n"
}
})
.disposed(by: notiBag)
Upvotes: 1
Reputation: 3728
This fatal error appears only in debug mode because it calls rxFataError only when you compile for debug. Its defined like this:
#if DEBUG
if AtomicIncrement(&_numberOfConcurrentCalls) > 1 {
rxFatalError("Warning: Recursive call or synchronization error!")
}
defer {
_ = AtomicDecrement(&_numberOfConcurrentCalls)
}
#endif
I just got this fatal error after an RxSwift update (3.4.0). My code updated Variable value in concurrent queue. Changed to serial queue fixed this crash.
Thierry
Upvotes: 1