首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >协议扩展不适用于RCT_EXPORT_VIEW_PROPERTY?

协议扩展不适用于RCT_EXPORT_VIEW_PROPERTY?
EN

Stack Overflow用户
提问于 2017-02-24 17:57:04
回答 1查看 391关注 0票数 1

我有一个部分基类RNChartBaseView (协议和扩展),以及一堆像RNLineChartView,RNBarChartView等的子类。

RNChartBaseView.swift

代码语言:javascript
运行
复制
 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

代码语言:javascript
运行
复制
 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

代码语言:javascript
运行
复制
 @objc(RNLineChartViewManagerSwift)
 class RNLineChartViewManagerSwift: RCTViewManager {
   override func view() -> UIView! {
     let ins = RNLineChartView()
     return ins;
   }       
 }

RNLineChartViewManager.m

代码语言:javascript
运行
复制
 #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

代码语言:javascript
运行
复制
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

代码语言:javascript
运行
复制
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中

代码语言:javascript
运行
复制
class RNChartViewBaseClass: UIView, RNChartViewBase {
      ......
      func setData(_ data: NSDictionary) {
          (self as RNChartViewBase).setData(data)
      }
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-02-24 21:22:56

问题是Objective-C对协议扩展一无所知,而同时React-Native正在使用Objective-C的消息传递机制(Objc_msgSend)。您不能使用协议扩展来注入一个方法,以便它对Objective-C的消息传递机制是可见的。

您可以创建UIView子类并在那里声明setData方法,而不是协议。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/42435599

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档