2017-02-24 86 views
1

我有一個部分鹼基類RNChartBaseView(協議和延伸),和亞類等RNLineChartView,RNBarChartView等協議擴展不適用於RCT_EXPORT_VIEW_PROPERTY?

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'

,如果我從擴展RNLineChartView.swift複製使用setData,每一件事工作正常。

問題在哪裏?

更新

看起來基類是必要的。

但下面的代碼不是優雅的,如何以正確的方式編寫它?

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) 
     } 
} 

回答

1

的問題是,Objective-C的同時,在同一時間做出反應,本地使用Objective-C的消息機制(objc_msgSend)一無所知協議擴展。 您不能使用協議擴展來注入方法,以便它對Objective-C的消息傳遞機制可見。

代替協議,您可以創建UIView的子類並在那裏聲明setData方法。

+0

UIView的子類帶來了一個新問題。 如果我創建UIView的子類並在那裏聲明setData方法。在setData中,有'chart.data = chartData',但圖表是通用類型, 我只能在具體的RNLineChartView/RNBarChartView中初始化'chart', 如何解決這個問題? –

+0

如果我正確理解你,你可以在父類中聲明setData,並在具有類型的子類中覆蓋方法。 –

+0

我更新了一些問題,在那裏添加我的基類。我對這個基礎班不太滿意,你能幫我改進嗎? –