当我将 RxSwift 的 DelegateProxy 与 FSCalendar 一起使用时发生错误
Posted
技术标签:
【中文标题】当我将 RxSwift 的 DelegateProxy 与 FSCalendar 一起使用时发生错误【英文标题】:error occurred when I using RxSwift's DelegateProxy with FSCalendar 【发布时间】:2021-08-21 11:16:53 【问题描述】:RxFSCalendarDelegateProxy.swift
import Foundation
import RxSwift
import RxCocoa
import FSCalendar
class RxFSCalendarDelegateProxy: DelegateProxy<FSCalendar, FSCalendarDelegate>, DelegateProxyType, FSCalendarDelegate
static func registerKnownImplementations()
self.register (calendar) -> RxFSCalendarDelegateProxy in
RxFSCalendarDelegateProxy(parentObject: calendar, delegateProxy: self)
static func currentDelegate(for object: FSCalendar) -> FSCalendarDelegate?
return object.delegate
static func setCurrentDelegate(_ delegate: FSCalendarDelegate?, to object: FSCalendar)
object.delegate = delegate
extension Reactive where Base: FSCalendar
var delegate : DelegateProxy<FSCalendar, FSCalendarDelegate>
return RxFSCalendarDelegateProxy.proxy(for: self.base)
var didSelect : Observable<Date>
return delegate.methodInvoked(#selector(FSCalendarDelegate.calendar(_:didSelect:at:)))
.map( (params) in
return params[1] as? Date ?? Date()
)
MainViewController.swift
import UIKit
import ReactorKit
import FSCalendar
class MainViewController: BaseViewController, View
typealias Reactor = MainViewReactor
let calendar = FSCalendar()
let label = UILabel()
init(reactor: Reactor)
super.init()
defer self.reactor = reactor
required init?(coder: NSCoder)
fatalError("init(coder:) has not been implemented")
override func viewDidLoad()
super.viewDidLoad()
override func setupLayout()
self.view.addSubview(calendar)
override func makeConstraints()
self.calendar.snp.makeConstraints
$0.bottom.equalToSuperview()
$0.top.equalToSuperview()
$0.left.equalToSuperview()
$0.right.equalToSuperview()
func bind(reactor: MainViewReactor)
// MARK: input
calendar.rx.didSelect.asObservable()
.map Reactor.Action.setDay($0)
.bind(to: reactor.action)
.disposed(by: disposeBag)
// MARK: output
我正在尝试将 FSCalendarDelegate 函数更改为 Observable 以使用 ReactorKit。 但是当我运行这段代码时,发生了错误 “RxCocoa/DelegateProxy.swift:230:致命错误:在隐式展开可选值时意外发现 nil” 我不知道如何修复我的 DelegateProxy。为什么 aSelector 为零?
【问题讨论】:
【参考方案1】:您发现了一个错误。代码崩溃是因为 FSCalendar 询问委托是否响应选择器,但选择器是 nil
。 FSCalendar 和 RxCocoa 都没有检查选择器是否为 nil。
I have submitted a pull request to the RxSwift repository to correct this problem.
在等待拉取请求通过系统时,您可以继承 DelegateProxy 并覆盖违规方法:
class MyDelegateProxy<P: AnyObject, D>: DelegateProxy<P, D>
override open func responds(to aSelector: Selector!) -> Bool
guard aSelector != nil else return false
return super.responds(to: aSelector)
class RxFSCalendarDelegateProxy: MyDelegateProxy<FSCalendar, FSCalendarDelegate>, DelegateProxyType, FSCalendarDelegate
static func registerKnownImplementations()
self.register (calendar) -> RxFSCalendarDelegateProxy in
RxFSCalendarDelegateProxy(parentObject: calendar, delegateProxy: self)
static func currentDelegate(for object: FSCalendar) -> FSCalendarDelegate?
return object.delegate
static func setCurrentDelegate(_ delegate: FSCalendarDelegate?, to object: FSCalendar)
object.delegate = delegate
至于为什么aSelector
为nil... 当FSCalendar 想要使用委托方法时,它首先检查该方法是否已实现。如果没有,那么它会检查是否实现了该方法的弃用版本。如果没有弃用的版本,那么它会询问代理是否实现了nil
方法。 FSCalender 这样做对我来说有点愚蠢,但显然如果这是在传统的委托实现上完成的,操作系统会以 false 响应。 RxCocoa 只是假设没有库会这样做。
【讨论】:
以上是关于当我将 RxSwift 的 DelegateProxy 与 FSCalendar 一起使用时发生错误的主要内容,如果未能解决你的问题,请参考以下文章