无法将变量传递到一个特定的 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
}
}
处理一个 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
}
}