Swift - 设置后无法访问类型别名属性
Swift - unable to access typealias properties once set
我有一大堆 UIView 对象是使用名为 'SheetField' 的 class 创建的。
对象通常在整个应用程序中初始化如下:
objectx = SheetField(title: "example", value: "example")
我需要向这些对象添加额外的 属性 'letter' 以在应用程序的一部分中访问,因此我创建了一个类型别名,如下所示:
typealias NewSheetField = (field: SheetField, letter: String?)
因此,我声明这些字段对象如下:
private var fieldX: NewSheetField
private var fieldY: NewSheetField
private var fieldZ: NewSheetField
我这样初始化它们:
fieldX = NewSheetField(field: SheetField(title: "example", value: "example"), letter: nil)
fieldY = NewSheetField(field: SheetField(title: "example", value: "example"), letter: nil)
fieldZ = NewSheetField(field: SheetField(title: "example", value: "example"), letter: nil)
然后我想为这些字段分配特定的字母。所以,我有一个字母字典:
private let letters = [0: "A", 1: "B", 2: "C", 3: "D", 4: "E", 5: "F", 6: "G", 7: "H"]
以及应用字母值的循环:
func createLettersForFields(fields: [NewSheetField]) {
for (index, var f) in fields.enumerated() {
if let letterToAdd = letters[index] {
f.letter = letterToAdd
}
}
}
所以我这样调用函数:
createLettersForFields(fields: [fieldX, fieldY, fieldZ]
但是,我似乎无法正确分配字母。我在循环中添加了几个打印语句:
func createLettersForFields(fields: [NewSheetField]) {
for (index, var f) in fields.enumerated() {
if let letterToAdd = letters[index] {
f.letter = letterToAdd
print("\(f.letter)")
print("\(fieldX.letter)")
}
}
}
循环显然每次都打印出 f.letter 正常(f 是我们传入的字段)但它根本不会打印出特定的字段字母 - 值始终为零。我所期望的是 print("(fieldX.letter)") 将打印 nil 直到循环命中 fieldX 字段然后打印分配的值。显然 print 语句并不重要,但它解释了为什么我无法在需要它的其他函数中访问 fieldX.letter。
如有任何帮助,我们将不胜感激。
更新:
我在循环中添加了条件语句如下:
if f == fieldX {
print("TEST")
}
并在此条件下添加了一个断点。我从来没有这么清楚地击中这部分,我在这里使用的 'f' 不等于我正在初始化的字段......然而当我从函数打印 'f' 并打印 'fieldX' 从 init 开始,它们似乎是同一个对象:
PRINTED FROM METHOD: (field: <SheetField: 0x125e56240; frame = (0 0; 0 0); layer = <CALayer: 0x2824c70a0>>, letter: Optional("A"))
PRINTED FROM INIT : (field: <SheetField: 0x125e56240; frame = (0 0; 0 0); layer = <CALayer: 0x2824c70a0>>, letter: nil)
更新 2:
奇怪的事情发生了!我简化了for循环,把枚举的部分去掉:
func createLettersForFields(fields: [NewSheetField]) {
for var field in fields {
if field == fieldX {
fieldX.letter = "A"
}
}
}
这有效并将 'A' 分配给 fieldX。当我登录 fieldX.letter 时,我得到 "A"。但是,当我将 'fieldX' 换成 'field' 时,它仍然不会分配:
func createLettersForFields(fields: [NewSheetField]) {
for var field in fields {
if field == fieldX {
field.letter = "A"
}
}
}
这里,打印日志returns nil。
当然,当它到达 field.letter = "A" 时,字段是 fieldX !
您陷入了 值类型陷阱。
在这一行
for (index, var f) in fields.enumerated() {
f
是fields
的副本,参数数组和对象fieldX
、fieldY
和fieldZ
保持不变。你不奇怪你没有得到关于 fields
cannot be modified because it's a constant?
的错误
连数组[fieldX, fieldY, fieldZ]
中的字段都是三个字段的副本
如果保留对原始对象的引用至关重要,请使用 类 引用类型。
否则您必须将数组创建为变量,将其作为 inout
传递并直接修改数组中的项目。请注意,枚举中的 element
未使用,因为您必须将 letterToAdd
直接分配给数组中的项目
由于 letter
是可选的,可选的绑定是多余的
private var fieldX = NewSheetField(field: SheetField(title: "example", value: "example"), letter: nil)
private var fieldY = NewSheetField(field: SheetField(title: "example", value: "example"), letter: nil)
private var fieldZ = NewSheetField(field: SheetField(title: "example", value: "example"), letter: nil)
private let letters = [0: "A", 1: "B", 2: "C", 3: "D", 4: "E", 5: "F", 6: "G", 7: "H"]
func createLettersForFields(fields: inout [NewSheetField]) {
for (index, _) in fields.enumerated() {
fields[index].letter = letters[index]
}
}
var theFields = [fieldX, fieldY, fieldZ]
createLettersForFields(fields: &theFields)
print(theFields)
请注意,即使采用这种方式,private var fieldX/Y/Z
的内容也不会改变。
我有一大堆 UIView 对象是使用名为 'SheetField' 的 class 创建的。
对象通常在整个应用程序中初始化如下:
objectx = SheetField(title: "example", value: "example")
我需要向这些对象添加额外的 属性 'letter' 以在应用程序的一部分中访问,因此我创建了一个类型别名,如下所示:
typealias NewSheetField = (field: SheetField, letter: String?)
因此,我声明这些字段对象如下:
private var fieldX: NewSheetField
private var fieldY: NewSheetField
private var fieldZ: NewSheetField
我这样初始化它们:
fieldX = NewSheetField(field: SheetField(title: "example", value: "example"), letter: nil)
fieldY = NewSheetField(field: SheetField(title: "example", value: "example"), letter: nil)
fieldZ = NewSheetField(field: SheetField(title: "example", value: "example"), letter: nil)
然后我想为这些字段分配特定的字母。所以,我有一个字母字典:
private let letters = [0: "A", 1: "B", 2: "C", 3: "D", 4: "E", 5: "F", 6: "G", 7: "H"]
以及应用字母值的循环:
func createLettersForFields(fields: [NewSheetField]) {
for (index, var f) in fields.enumerated() {
if let letterToAdd = letters[index] {
f.letter = letterToAdd
}
}
}
所以我这样调用函数:
createLettersForFields(fields: [fieldX, fieldY, fieldZ]
但是,我似乎无法正确分配字母。我在循环中添加了几个打印语句:
func createLettersForFields(fields: [NewSheetField]) {
for (index, var f) in fields.enumerated() {
if let letterToAdd = letters[index] {
f.letter = letterToAdd
print("\(f.letter)")
print("\(fieldX.letter)")
}
}
}
循环显然每次都打印出 f.letter 正常(f 是我们传入的字段)但它根本不会打印出特定的字段字母 - 值始终为零。我所期望的是 print("(fieldX.letter)") 将打印 nil 直到循环命中 fieldX 字段然后打印分配的值。显然 print 语句并不重要,但它解释了为什么我无法在需要它的其他函数中访问 fieldX.letter。
如有任何帮助,我们将不胜感激。
更新:
我在循环中添加了条件语句如下:
if f == fieldX {
print("TEST")
}
并在此条件下添加了一个断点。我从来没有这么清楚地击中这部分,我在这里使用的 'f' 不等于我正在初始化的字段......然而当我从函数打印 'f' 并打印 'fieldX' 从 init 开始,它们似乎是同一个对象:
PRINTED FROM METHOD: (field: <SheetField: 0x125e56240; frame = (0 0; 0 0); layer = <CALayer: 0x2824c70a0>>, letter: Optional("A"))
PRINTED FROM INIT : (field: <SheetField: 0x125e56240; frame = (0 0; 0 0); layer = <CALayer: 0x2824c70a0>>, letter: nil)
更新 2:
奇怪的事情发生了!我简化了for循环,把枚举的部分去掉:
func createLettersForFields(fields: [NewSheetField]) {
for var field in fields {
if field == fieldX {
fieldX.letter = "A"
}
}
}
这有效并将 'A' 分配给 fieldX。当我登录 fieldX.letter 时,我得到 "A"。但是,当我将 'fieldX' 换成 'field' 时,它仍然不会分配:
func createLettersForFields(fields: [NewSheetField]) {
for var field in fields {
if field == fieldX {
field.letter = "A"
}
}
}
这里,打印日志returns nil。 当然,当它到达 field.letter = "A" 时,字段是 fieldX !
您陷入了 值类型陷阱。
在这一行
for (index, var f) in fields.enumerated() {
f
是fields
的副本,参数数组和对象fieldX
、fieldY
和fieldZ
保持不变。你不奇怪你没有得到关于 fields
cannot be modified because it's a constant?
连数组[fieldX, fieldY, fieldZ]
中的字段都是三个字段的副本
如果保留对原始对象的引用至关重要,请使用 类 引用类型。
否则您必须将数组创建为变量,将其作为 inout
传递并直接修改数组中的项目。请注意,枚举中的 element
未使用,因为您必须将 letterToAdd
直接分配给数组中的项目
由于 letter
是可选的,可选的绑定是多余的
private var fieldX = NewSheetField(field: SheetField(title: "example", value: "example"), letter: nil)
private var fieldY = NewSheetField(field: SheetField(title: "example", value: "example"), letter: nil)
private var fieldZ = NewSheetField(field: SheetField(title: "example", value: "example"), letter: nil)
private let letters = [0: "A", 1: "B", 2: "C", 3: "D", 4: "E", 5: "F", 6: "G", 7: "H"]
func createLettersForFields(fields: inout [NewSheetField]) {
for (index, _) in fields.enumerated() {
fields[index].letter = letters[index]
}
}
var theFields = [fieldX, fieldY, fieldZ]
createLettersForFields(fields: &theFields)
print(theFields)
请注意,即使采用这种方式,private var fieldX/Y/Z
的内容也不会改变。