无法将变量传递到一个特定的 class,实例成员不能用于类型错误

Cannot get variable passed into one specific class, instance member cannot be used on type error

处理一个 Storyboard 视图需要两个 classes,一个普通的 UIViewController class 和一个与 iOS-Charts 库一起工作的 IAxisValueFormatter class 的项目用字符串值标记一个轴。这些 class 相关部分及其原始(故障排除前)形式如下所示:

import Foundation
import Charts

@objc(BarChartFormatter)
public class BarChartFormatter: NSObject, IAxisValueFormatter{

    var dates: [String]!

    public func stringForValue(_ value: Double, axis: AxisBase?) -> String {
        return dates[Int(value)]
    }
}

class SessionRevew: UIViewController {

    @IBOutlet weak var HBCController: HorizontalBarChartView!
    var dates: [String]!

问题是我无法将任何值传递到 IAxisValueFormatter class。将值从以前的视图控制器传递到 SessionRevew class 是无痛的并且继续工作。

来自另一个视图控制器的以下代码成功地将日期数组传递给 UIViewController class SessionRevew:

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if (segue.identifier == "ReviewData") {
        let datespass = segue.destination as! SessionRevew
        datespass.dates = dates
    }
}

然而,只要添加代码将相同的变量传递给另一个class:

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if (segue.identifier == "ReviewData") {
        let datespass1 = segue.destination as! BarChartFormatter
        let datespass = segue.destination as! SessionRevew
        datespass1.dates = dates
        datespass.dates = dates
    }
}

代码变得可操作,因为 segue 的激活触发了这个错误: EXC_BAD_INSTRUCTION error

发生在以下行: 让 datespass1 = segue.destination 作为! BarChartFormatter 如果有人能帮助我理解失败的原因以及如何将数组传递给那个 class,这就是理想的答案。也就是说,以下内容代表了一些回避的努力通过将 SessionRevew class 中的变量共享给另一个 class 来解决此错误。我们首先在另一个class中创建了一个辅助变量,结果是:

@objc(BarChartFormatter)
public class BarChartFormatter: NSObject, IAxisValueFormatter{

    var BCFdates = SessionRevew.dates

    public func stringForValue(_ value: Double, axis: AxisBase?) -> String {
        return BCFdates[Int(value)]
    }
}

由于错误 "Instance member 'dates' cannot be used on type SessionRevew",该代码将无法编译,该错误发生在以下行:

var BCFdates = SessionRevew.dates

我们尝试将上面的 class 嵌套在 SessionRevew class 中,这产生了完全相同的错误。在尝试解决此错误时,我们找到了此处显示的解决方案:,并尝试像这样实现它:

import Foundation
import Charts

class SessionRevew: UIViewController {

    @IBOutlet weak var HBCController: HorizontalBarChartView!

    var dates: [String]!

    @objc(BarChartFormatter)
    public class BarChartFormatter: NSObject, IAxisValueFormatter{

        var BCFdates: [String] {
            get {
                return {
                    SessionRevew.dates
                    }
                }
        }

        public func stringForValue(_ value: Double, axis: AxisBase?) -> String {
            return BCFdates[Int(value)]
        }
    }
}

不幸的是,错误仍然完全相同 ("Instance member 'dates' cannot be used on type SessionRevew"),代码无法编译。取消嵌套 class 给出:

import Foundation
import Charts

@objc(BarChartFormatter)
public class BarChartFormatter: NSObject, IAxisValueFormatter{

    var BCFdates: [String] {
        get {
            return {
                SessionRevew.dates
            }
        }
    }

    public func stringForValue(_ value: Double, axis: AxisBase?) -> String {
        return BCFdates[Int(value)]
    }
}

class SessionRevew: UIViewController {

    @IBOutlet weak var HBCController: HorizontalBarChartView!
    var dates: [String]!
}

此代码还会生成错误代码:"Instance member 'dates' cannot be used on type SessionRevew"。然后尝试根据类似问题的解决方案将 BCFdates 变量定义为只读计算 属性:

var BCFdates: [String] {
    return SessionRevew{dates}
}

但是编译错误依然存在。使此代码正常工作的任何解决方案或解释将不胜感激。如前所述,如果我们可以将数组直接传递给 BarChartFormatter class 而忘记 class 之间的共享问题,那将是理想的。

编辑

函数 setChart 在 SessionRevew class 中使用 BarChartFormatter 的方式如下:

func setChart(_ dataPoints: [String], values: [Double]) {
    let formato:BarChartFormatter = BarChartFormatter()

for i in 0..<dataPoints.count {
        let dataEntry = BarChartDataEntry(x: Double(i), yValues: [values[i]])
        dataEntries.append(dataEntry)
        formato.stringForValue(Double(i), axis: xaxis)
    }
    xaxis.valueFormatter = formato
    HBCController.xAxis.valueFormatter = xaxis.valueFormatter
}

代码中的其他任何地方都没有引用它。

正如 Phillip 所建议的,解决方案是放弃在 segue 期间将变量传递给 BarChartFormatter 的尝试,而是在 setChart 函数中转发变量。

只需要一行新代码:

    formato.dates = self.dates

这会立即添加到 setChart 函数中:

    let formato:BarChartFormatter = BarChartFormatter()

原始的 BarChartFormatter 代码(如下所示)与日期数组完美配合。

@objc(BarChartFormatter)
public class BarChartFormatter: NSObject, IAxisValueFormatter{

    var dates: [String]!

    public func stringForValue(_ value: Double, axis: AxisBase?) -> String {
        return dates[Int(value)]
    }
}

此外,正如 Phillip 指出的那样,使用 segue.destination 代码无法将日期数组传递给 BarChartFormatter class,因此不得尝试这样做。因此,该代码的这个版本是正确的:

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if (segue.identifier == "ReviewData") {
        let datespass = segue.destination as! SessionRevew
        datespass.dates = dates
    }
}