如何抑制 RxSwift 中的指定错误?

How to suppress a specify error in RxSwift?

当运行在Debug方案中,第30行出现致命错误,如果你的代码是这样的。

https://github.com/ReactiveX/RxSwift/blob/master/RxSwift/Observables/Implementations/Sink.swift

rxFatalError("Warning: Recursive call or synchronization error!")

如果我从 Debug 到 Release 选择 运行 方案。致命错误不会显示。但是我想知道我是否可以做些什么来抑制它。

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")

这个致命错误只在调试模式下出现,因为它只在你编译调试时调用 rxFataError。它的定义是这样的:

#if DEBUG
    if AtomicIncrement(&_numberOfConcurrentCalls) > 1 {
        rxFatalError("Warning: Recursive call or synchronization error!")
    }

    defer {
        _ = AtomicDecrement(&_numberOfConcurrentCalls)
    }
#endif

我刚刚在 RxSwift 更新 (3.4.0) 后遇到这个致命错误。我的代码更新了并发队列中的变量值。更改为串行队列修复了此崩溃。

蒂埃里

您可以在不使用 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)

我将@thierryb 的答案标记为正确答案。已知正确答案如下

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)

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)