【问题标题】:error occurred when I using RxSwift's DelegateProxy with FSCalendar当我将 RxSwift 的 DelegateProxy 与 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 为零?

【问题讨论】:

    标签: swift delegates rx-swift fscalendar


    【解决方案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 只是假设没有库会这样做。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-02-02
      • 1970-01-01
      • 2021-08-28
      • 2020-10-26
      • 1970-01-01
      • 1970-01-01
      • 2020-12-06
      相关资源
      最近更新 更多