我有一个部分基类RNChartBaseView (协议和扩展),以及一堆像RNLineChartView,RNBarChartView等的子类。
RNChartBaseView.swift
 protocol RNChartBaseView {
      associatedtype T: ChartViewBase;
      associatedtype U: ChartDataEntryBase;
      var chart: T { get }
      func createEntries(_ data: NSDictionary) -> [U];
      func setData(_ data: NSDictionary);
 }
 extension RNChartBaseView  {
       func setData(_ data: NSDictionary) {
           
           let chartData = createEntries(data);
           chart.data = chartData;
       }
 }RNLineChartView.swift
 class RNLineChartView : UIView, RNChartBaseView{
      let _chart:LineChartView;
     
      var chart: LineChartView {
         return _chart
      }
      override init(frame: CGRect) {
         self._chart = LineChartView(frame: frame);
         super.init(frame: frame);
         self.addSubview(_chart);
      }
      func createEntries(_ data: NSDictionary) -> [LineDataEntry] {
        // ....... convert to LineDataEntry array.
        return entries;
      }
 }RNLineChartViewManagerSwift.swift
 @objc(RNLineChartViewManagerSwift)
 class RNLineChartViewManagerSwift: RCTViewManager {
   override func view() -> UIView! {
     let ins = RNLineChartView()
     return ins;
   }       
 }RNLineChartViewManager.m
 #import "React/RCTViewManager.h"
 @interface RCT_EXTERN_MODULE(RNLineChartViewManagerSwift, RCTViewManager)
 RCT_EXPORT_VIEW_PROPERTY(data, NSDictionary)
 @end但我得到了
[reactNativeCharts.RNLineChartView setData:]: unrecognized selector sent to instance 0x7fdf60e04510'
如果我将setData从扩展复制到RNLineChartView.swift,一切都会正常工作。
问题出在哪里?
更新
似乎基类是必要的。
但是下面的代码并不优雅,如何以适当的方式编写它?
RNChartBaseViewClass
class RNChartBaseViewClass: UIView, RNChartBaseView {
    
    var chart: ChartViewBase {
        fatalError("subclass should override this function.")
    };
    
    override init(frame: CGRect) {
        fatalError("subclass should override this function.")
    }
    func createEntries(_ data: NSDictionary) -> [BaseChartDataEntry] {
        fatalError("subclass should override this function.") 
    }
    func setData(_ data: NSDictionary) {
        let chartData = createEntries(data);
        chart.data = chartData;
    }
}RNLineChartView.swift
class RNLineChartView : RNChartBaseViewClass{
      var _chart : LineChartView;
      override var chart: LineChartView {
         return _chart
      }
      override init(frame: CGRect) {
         self._chart = LineChartView(frame: frame);
         super.init(frame: frame);
         self.addSubview(_chart);
      }
      override func createEntries(_ data: NSDictionary) -> [BaseChartDataEntry] { 
           // I have to use [BaseChartDataEntry] here as return type to pass compile,
           //  although it actually is [LineDataEntry],  it may cause further problems, e.g. 
        // ....... convert to LineDataEntry array.
        return entries;
      }
 }更新
最后,我使用了扩展和子类的组合。
模板代码在扩展中。在RNChartBaseViewClass中
class RNChartViewBaseClass: UIView, RNChartViewBase {
      ......
      func setData(_ data: NSDictionary) {
          (self as RNChartViewBase).setData(data)
      }
}发布于 2017-02-24 21:22:56
问题是Objective-C对协议扩展一无所知,而同时React-Native正在使用Objective-C的消息传递机制(Objc_msgSend)。您不能使用协议扩展来注入一个方法,以便它对Objective-C的消息传递机制是可见的。
您可以创建UIView子类并在那里声明setData方法,而不是协议。
https://stackoverflow.com/questions/42435599
复制相似问题