結論としてRxCocoaの機能を誤使用したけど、Carthage経由で導入した場合はクラッシュせずにCocoaPods経由で導入した場合にクラッシュするという内容です。
■前提
RxSwift: 4.5.0
RxCocoa: 4.5.0
■間違った使い方例
func viewDidLoad() {
self.tableView.delegate = self.dataSource
self.tableView.dataSource = self.dataSource
viewModel.articles
.asDriver()
.drive(
self.tableView.rx.items(dataSource: self.dataSource)
)
.disposed(by: disposeBag)
}
この場合本来であれば以下のような理由でクラッシュするはずです。
This is a feature to warn you that there is already a delegate (or data source) set somewhere previously.
The action you are trying to perform will clear that delegate (data source) and that means that some of your features
that depend on that delegate (data source) being set will likely stop working.\n
すでにどこかでデータソースまたはデリゲートが設定されていますよーって感じのエラーですが、まさにviewDidLoadの頭で明示的に両方設定してるのでダメですね笑
ただこのエラー、うちの環境ではRxSwift(RxCocoa)をCarthageで導入した場合は発生せずに(本来の使い方じゃないけど)意図した通りに動きますが、CocoaPodsで導入した場合にはしっかりとエラーが発生してクラッシュします。。。
またさらにわからないのはSchemeのBuildConfigurationでDebugビルドを行った時のみに発生し、Releaseやそれ以外(独自で設定した場合)の場合も発生しません。
※これはソースをちゃんと追ってないのですが、RxCocoaのなかでif DEBUGで分岐しているのかもしれません。
Qiitaの使い方にそぐわないかもしれませんが、もし同じ事象に遭遇して原因を突き止めた方がいらっしゃいましたら、ご教授いただけたら幸いです。
よろしくお願いします。
====5/27追記======
まず実際にクラッシュする箇所(エラー)ですが、DelegateProxyType.swiftのinstallForwardDelegateメソッド内にある assert(proxy._forwardToDelegate() === nil・・・
に引っかかることで、発生してます。
で、そもそもXcodeのデフォルト設定ではreleaseビルドはswift optimazation levelが-O
で設定されており、この場合 assert
は評価されずにスキップされます。
※Debugビルドのデフォルトは -Onone
であり、この場合は assert
も評価され、引っかかったら RuntimeError
になります。
これが SchemeのBuildConfigurationでDebugビルドを行った時のみに発生し、Releaseやそれ以外(独自で設定した場合)の場合も発生しません。
の原因(理由)でした。
またうちでは以下のコマンドでCarthage経由で各ライブラリをインストールしてます。
carthage update --platform iOS --no-use-binaries
carthage update
コマンドには --configuration
というオプションがあり、ここで Debug
と明示的に指定した場合にDebugビルドとなり、上記の理由によりCocoaPodsで導入した時に発生したエラーが再現できました。
※--configuration
を付与しなかった場合のデフォルトはReleaseなのでしょうか??
わかってしまえば簡単な内容だったので、勉強不足を痛感しております。。。
もし同じような理由でハマってる方の一助になれば幸いです。