当我将 RxSwift 的 DelegateProxy 与 FSCalendar 一起使用时发生错误
error occurred when I using RxSwift's DelegateProxy with FSCalendar
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 {
[=11=].bottom.equalToSuperview()
[=11=].top.equalToSuperview()
[=11=].left.equalToSuperview()
[=11=].right.equalToSuperview()
}
}
func bind(reactor: MainViewReactor) {
// MARK: input
calendar.rx.didSelect.asObservable()
.map { Reactor.Action.setDay([=11=]) }
.bind(to: reactor.action)
.disposed(by: disposeBag)
// MARK: output
}
}
我正在尝试将 FSCalendarDelegate 函数更改为 Observable 以使用 ReactorKit。
但是当我 运行 这段代码时,发生了错误
“RxCocoa/DelegateProxy.swift:230:致命错误:在隐式展开可选值时意外发现 nil”
我不知道如何修复我的 DelegateProxy。为什么 aSelector 为零?
您发现了一个错误。代码崩溃是因为 FSCalendar 询问委托是否响应选择器,但选择器是 nil
。 FSCalendar 和 RxCocoa 都没有检查选择器是否为 nil。
I have submitted a pull request to the RxSwift repository to correct this problem.
在等待拉取请求通过系统时,您可以子class 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 这样做对我来说感觉有点傻,但显然如果这是在传统委托实现上完成的,OS 会以 false 响应。 RxCocoa 只是假设没有图书馆会这样做。
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 {
[=11=].bottom.equalToSuperview()
[=11=].top.equalToSuperview()
[=11=].left.equalToSuperview()
[=11=].right.equalToSuperview()
}
}
func bind(reactor: MainViewReactor) {
// MARK: input
calendar.rx.didSelect.asObservable()
.map { Reactor.Action.setDay([=11=]) }
.bind(to: reactor.action)
.disposed(by: disposeBag)
// MARK: output
}
}
我正在尝试将 FSCalendarDelegate 函数更改为 Observable 以使用 ReactorKit。 但是当我 运行 这段代码时,发生了错误 “RxCocoa/DelegateProxy.swift:230:致命错误:在隐式展开可选值时意外发现 nil” 我不知道如何修复我的 DelegateProxy。为什么 aSelector 为零?
您发现了一个错误。代码崩溃是因为 FSCalendar 询问委托是否响应选择器,但选择器是 nil
。 FSCalendar 和 RxCocoa 都没有检查选择器是否为 nil。
I have submitted a pull request to the RxSwift repository to correct this problem.
在等待拉取请求通过系统时,您可以子class 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 这样做对我来说感觉有点傻,但显然如果这是在传统委托实现上完成的,OS 会以 false 响应。 RxCocoa 只是假设没有图书馆会这样做。