object 类型的变量作为数组行为不当
variable of object type as an Array misbehaving
环境XCode6.4Swift2.something
我有两个简单的自定义 Classes
class Stock {
var ageArray = [3,6,9,12,15,18,24,30,36,42,48,54,60,66,72] // in months
var beastArray = ["Angus","Braford","Charolais","Droughtmaster","Euro","Hereford"]
var breedArray = ["Calves","Vealers","Weaners","Heifers","Steers","Cows","Bulls"]
var priceArray = [600.00,650.00,700.00,750.00,800.00,850.00,900.00,950.00,1000.00,]
}
和
class Sale {
var age : Int = 0
var beast : String = " "
var breed : String = " "
var price : Double = 0.00
}
现在到我的视图控制器
我已经实例化了来自 Sale Class 的报告。 ViewController 包含所有这些报告的数组,正如我在许多地方所教的那样,首先声明它并在 viewDidLoad
中实例化它
class ViewController: UIViewController, UIPickerViewDelegate, UIPickerViewDataSource {
@IBOutlet weak var picker: UIPickerView!
var report = Sale()
var sheets = Stock()
var saleArray : [Sale] = [] // declaration
override func viewDidLoad() {
super.viewDidLoad()
saleArray = [Sale]() // instantiating
}
选择器的其他委托函数工作得很好,不需要在这里展示它们,但这是两个 class Object 相遇传递值的地方
func pickerView(picker: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
switch(component) {
case 0:
report.breed = sheets.breedArray[row]
break
case 1:
report.beast = sheets.beastArray[row]
break
case 2:
report.age = sheets.ageArray[row]
break
default:
report.price = sheets.priceArray[row]
break
}
}
屏幕上的按钮将它们加载到数组中
@IBAction func AcceptValues(sender:UIButton) {
saleArray.append(report)
}
仅此而已。
这是在调试器中看到的结果,断点设置如下 3 次后 [0] 应该有 Angus Calves 和 [1] 有 Droughtmaster Heifers
所以问题是为什么 saleArray 会填满 n 个最后输入的实例?我知道我不是在看最后一个条目 n 次。但奇怪的是,报告地址都是7A19C000。
我认为可能是viewDidLoad中instatiaton后编译器无法推断数组类型。检查各种教程和随附的代码或多或少地处理了我在上面所做的事情。这就是标题的原因,我确定 Swift 可以容纳一个 objects 的数组,而不是通常的数组。
我什至花钱买了两本 Matt Neuberg 的书,只是为了检查如何设置 Object 阵列,但就像所有可用的 material他们只讨论 Int 和 Double 和 String 的数组,仅此而已。有时最令人恼火的错误是最多的 staring-at-you-in-your-face,我已经追查了将近一个星期。
代码没有其他内容。
编辑:
感谢下面的两位贡献者,评论显示了我为使其工作所做的工作。但我觉得它不优雅:
我还把 Stock 做了一个结构体。
class ViewController: UIViewController, UIPickerViewDelegate, UIPickerViewDataSource {
@IBOutlet weak var picker: UIPickerView!
@IBOutlet weak var textPanel: UITextView!
var sheets = Stock()
var saleArray : [Sale] = []
var localBreed = " " // introduced some handover values
var localBeast = " " // because report is out of scope
var localAge = 0 // in the picker functions
var localPrice = 0.00
。
.
.
@IBAction func AcceptValues(sender:UIButton) {
var report = Sale() // new reports instantiated here
report.breed = localBreed // and locals handover values to
report.beast = localBeast // report instance before adding
report.age = localAge // to array
report.price = localPrice
saleArray.append(report)
}
。
.
.
func pickerView(picker: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
switch(component) {
case 0:
localBreed = sheets.breedArray[row]
break
case 1:
localBeast = sheets.beastArray[row]
break
case 2:
localAge = sheets.ageArray[row]
break
default:
localPrice = sheets.priceArray[row]
break
}
}
我认为这是因为 report
是 Sale
的一个实例。因此,每次您 select 一个新的组合 - 您并不是在创建一个新的 Sale
项目,而是在更改与名为 report
的 Sale
的单个实例关联的值。当您按下按钮时,它会添加对该单个 report
实例的另一个引用。
这些 class 对象通过引用传递 - 即当您将 report
添加到 saleArray
时,它不会创建值的副本 - 而是将引用传递给实际实例。每次按下按钮时,您都会添加对 Sale
的同一实例的引用。当您使用选择器时,与该实例关联的值就会发生变化。这是一遍又一遍的相同实例。
您需要更改代码,以便为每个 selection 创建一个新的 Sale
实例。作为快速破解,要对此进行测试,您可以将代码添加到您的按钮,该按钮根据 selected 值创建一个新的 Sale
实例 - 然后将其添加到 saleArray
.
ETA - 我注意到的另一件事:您正在实例化 saleArray
两次 - 在 //declaration
和 viewDidLoad()
中。虽然这不会导致您描述的问题,但在潜在情况下可能会导致问题。
环境XCode6.4Swift2.something
我有两个简单的自定义 Classes
class Stock {
var ageArray = [3,6,9,12,15,18,24,30,36,42,48,54,60,66,72] // in months
var beastArray = ["Angus","Braford","Charolais","Droughtmaster","Euro","Hereford"]
var breedArray = ["Calves","Vealers","Weaners","Heifers","Steers","Cows","Bulls"]
var priceArray = [600.00,650.00,700.00,750.00,800.00,850.00,900.00,950.00,1000.00,]
}
和
class Sale {
var age : Int = 0
var beast : String = " "
var breed : String = " "
var price : Double = 0.00
}
现在到我的视图控制器
我已经实例化了来自 Sale Class 的报告。 ViewController 包含所有这些报告的数组,正如我在许多地方所教的那样,首先声明它并在 viewDidLoad
中实例化它class ViewController: UIViewController, UIPickerViewDelegate, UIPickerViewDataSource {
@IBOutlet weak var picker: UIPickerView!
var report = Sale()
var sheets = Stock()
var saleArray : [Sale] = [] // declaration
override func viewDidLoad() {
super.viewDidLoad()
saleArray = [Sale]() // instantiating
}
选择器的其他委托函数工作得很好,不需要在这里展示它们,但这是两个 class Object 相遇传递值的地方
func pickerView(picker: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
switch(component) {
case 0:
report.breed = sheets.breedArray[row]
break
case 1:
report.beast = sheets.beastArray[row]
break
case 2:
report.age = sheets.ageArray[row]
break
default:
report.price = sheets.priceArray[row]
break
}
}
屏幕上的按钮将它们加载到数组中
@IBAction func AcceptValues(sender:UIButton) {
saleArray.append(report)
}
仅此而已。
这是在调试器中看到的结果,断点设置如下 3 次后 [0] 应该有 Angus Calves 和 [1] 有 Droughtmaster Heifers
所以问题是为什么 saleArray 会填满 n 个最后输入的实例?我知道我不是在看最后一个条目 n 次。但奇怪的是,报告地址都是7A19C000。
我认为可能是viewDidLoad中instatiaton后编译器无法推断数组类型。检查各种教程和随附的代码或多或少地处理了我在上面所做的事情。这就是标题的原因,我确定 Swift 可以容纳一个 objects 的数组,而不是通常的数组。
我什至花钱买了两本 Matt Neuberg 的书,只是为了检查如何设置 Object 阵列,但就像所有可用的 material他们只讨论 Int 和 Double 和 String 的数组,仅此而已。有时最令人恼火的错误是最多的 staring-at-you-in-your-face,我已经追查了将近一个星期。
代码没有其他内容。
编辑: 感谢下面的两位贡献者,评论显示了我为使其工作所做的工作。但我觉得它不优雅: 我还把 Stock 做了一个结构体。
class ViewController: UIViewController, UIPickerViewDelegate, UIPickerViewDataSource {
@IBOutlet weak var picker: UIPickerView!
@IBOutlet weak var textPanel: UITextView!
var sheets = Stock()
var saleArray : [Sale] = []
var localBreed = " " // introduced some handover values
var localBeast = " " // because report is out of scope
var localAge = 0 // in the picker functions
var localPrice = 0.00
。 . .
@IBAction func AcceptValues(sender:UIButton) {
var report = Sale() // new reports instantiated here
report.breed = localBreed // and locals handover values to
report.beast = localBeast // report instance before adding
report.age = localAge // to array
report.price = localPrice
saleArray.append(report)
}
。 . .
func pickerView(picker: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
switch(component) {
case 0:
localBreed = sheets.breedArray[row]
break
case 1:
localBeast = sheets.beastArray[row]
break
case 2:
localAge = sheets.ageArray[row]
break
default:
localPrice = sheets.priceArray[row]
break
}
}
我认为这是因为 report
是 Sale
的一个实例。因此,每次您 select 一个新的组合 - 您并不是在创建一个新的 Sale
项目,而是在更改与名为 report
的 Sale
的单个实例关联的值。当您按下按钮时,它会添加对该单个 report
实例的另一个引用。
这些 class 对象通过引用传递 - 即当您将 report
添加到 saleArray
时,它不会创建值的副本 - 而是将引用传递给实际实例。每次按下按钮时,您都会添加对 Sale
的同一实例的引用。当您使用选择器时,与该实例关联的值就会发生变化。这是一遍又一遍的相同实例。
您需要更改代码,以便为每个 selection 创建一个新的 Sale
实例。作为快速破解,要对此进行测试,您可以将代码添加到您的按钮,该按钮根据 selected 值创建一个新的 Sale
实例 - 然后将其添加到 saleArray
.
ETA - 我注意到的另一件事:您正在实例化 saleArray
两次 - 在 //declaration
和 viewDidLoad()
中。虽然这不会导致您描述的问题,但在潜在情况下可能会导致问题。