【发布时间】:2019-02-10 12:51:48
【问题描述】:
在通过代码呈现新的 UIViewController 之后,在使用 .Drive 的每个位置(在 viewModel 或 viewController 中),我都会收到此错误:
drive* family of methods can be only called from MainThread
这就是我展示新 ViewController 的方式:
func goToVerifyPage() {
let verifyVC = VerifyViewController()
verifyVC.modalTransitionStyle = .flipHorizontal
self.present(verifyVC, animated: true, completion: nil)
}
在VerifyViewController内部:
override func viewDidLoad() {
super.viewDidLoad()
confirmVerifyCodeBTN.rx.tap
.asDriver()
.debounce(1)
.filter({
self.viewModel.signupEnabled
})
.drive(onNext:{ [weak self] _ in
guard let verifyCode = self?.verificationCodeTF.text else { return }
self?.verifyActivateCode(verifyCode)
}).disposed(by: disposeBag)
}
执行 .filter 行后显示的错误。
在之前的 viewController(名为 loginViewController)中,我使用相同的代码,但没有收到任何错误,verifyViewController 和 loginViewController 之间唯一不同的是,使用情节提要来呈现该 ViewController(loginViewController)。
更新: 当我使用此代码呈现 verifyViewController 时,一切正常:
func goToVerifyPage() {
DispatchQueue.main.async {
let verifyVC = VerifyViewController()
verifyVC.modalTransitionStyle = .flipHorizontal
self.present(verifyVC, animated: true, completion: nil)
}
}
【问题讨论】:
-
你的问题到底是什么?
-
为什么会这样?以及如何让代码运行?
-
发生这种情况是因为您没有按照库的要求在主线程上运行代码。而且你必须将它分派到正确的线程。
-
在confirmVerifyCodeBTN.rx.tap 行之前,我把Thread.isMainThread 和它返回true。每次我想使用 dispatch 呈现新的 ViewController 时,我认为这不是正确的方法。
-
添加 DispatchQueue.main.async 是一个很好的解决方案。更符合 rx-swift 的方式是使用:
.observeOn(MainScheduler.instance)