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

时间:2016-09-29 19:00:10

标签: ios swift class swift3 ios-charts

处理一个项目,其中一个Storyboard视图需要两个类,一个普通的UIViewController类和一个IAxisValueFormatter类,它与iOS-Charts库一起使用字符串值标记一个轴。这些类在相关部分和原始(故障排除前)表单中显示:

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类。将值从前一个视图控制器传递到SessionRevew类是轻松的,并继续工作。

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

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

但是,只要添加代码以将相同的变量传递给另一个类:

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 如果有人可以帮助我理解为什么会失败以及如何将数组传递给该类,这是理想的答案。这就是说,以下代表了通过共享变量来回避此错误的一些努力SessionRevew类到另一个类。我们首先在另一个类中创建了一个辅助变量,结果如下:

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

    var BCFdates = SessionRevew.dates

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

该代码将无法编译,因为错误“实例成员'日期'不能用于类型SessionRevew”,这发生在该行:

var BCFdates = SessionRevew.dates

我们尝试在SessionRevew类中嵌套上面的类,这产生了完全相同的错误。在尝试解决此错误时,我们找到了此处显示的解决方案:https://stackoverflow.com/a/32693285/6889264,并试图像这样实现它:

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

不幸的是,错误仍然完全相同(“实例成员'日期'不能用于类型SessionRevew”)并且代码无法编译。取消嵌套类给出了:

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]!
}

此代码还会生成错误代码:“实例成员'日期'不能用于类型SessionRevew”。然后尝试根据此解决方案将BCFdates变量定义为只读计算属性:https://stackoverflow.com/a/38651304/6889264

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

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

修改

BarChartFormatter由函数setChart以如下方式在SessionRevew类中使用:

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
}

它没有在代码中的任何其他位置引用。

1 个答案:

答案 0 :(得分:0)

正如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代码将date数组传递给BarChartFormatter类是不可能的,因此不能尝试。因此,该版本的代码是正确的:

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