I am constructing an array of booleans to store the state of the sections in a UICollectionView. It is a variable stored as a property of my UIViewController:
我正在构建一个布尔数组,用于在UICollectionView中存储节的状态。它是作为我的UIViewController的属性存储的变量:
var _weekSelections : Array<Bool>!
Then, in a function called by loadView(), I construct the array and assign a value to the first index:
然后,在loadView()调用的函数中,构造数组并为第一个索引赋值:
_weekSelections = Array<Bool>(count:_weekCount, repeatedValue:false)
_weekSelections[0] = true
The value at index 0 remains false! The array is constructed, and has multiple elements, but any assignment that I make to an index does not affect the value stored at that index, even if I check the value on the very next line of code. I know that Swift makes a copy of an array if I perform an action that may change its length, but I don't think this is a case where a copy would me made. The only way I can get any value to change is if I manually create a copy as follows:
索引0处的值仍为false!数组是构造的,并且有多个元素,但是我对索引的任何赋值都不会影响存储在该索引处的值,即使我检查下一行代码的值。我知道如果我执行一个可能改变其长度的动作,Swift会制作一个数组的副本,但我认为这不是我要制作副本的情况。我可以获得任何值更改的唯一方法是,如果我手动创建副本,如下所示:
var copy = _weekSelections
copy[0] = true
_weekSelections = copy
Am I missing something obvious or could this be a strange bug?
我错过了一些明显的东西,或者这可能是一个奇怪的错误?
2 个解决方案
#1
2
For the sake of having my code on SO rather than Pastebin, here's my observation. This looks like some kind of bug or unexpected behaviour when using an optional array in a Swift class derived from an Objective C class. If you use a plain Swift class, this works as expected:
为了让我的代码在SO而不是Pastebin上,这是我的观察。当在从Objective C类派生的Swift类中使用可选数组时,这看起来像某种错误或意外行为。如果您使用普通的Swift类,这可以按预期工作:
class Foo {
var weekSelections: Array<Bool>!
func test() {
weekSelections = Array<Bool>(count: 10, repeatedValue: false)
weekSelections[0] = true;
println(weekSelections[0]) // Prints "true"
}
}
var foo = Foo()
foo.test()
However, if you derive Foo from NSObject:
但是,如果从NSObject派生Foo:
import Foundation
class Foo : NSObject { // This derivation is the only difference from the code above
var weekSelections: Array<Bool>!
func test() {
weekSelections = Array<Bool>(count: 10, repeatedValue: false)
weekSelections[0] = true;
println(weekSelections[0]) // Prints "false"
}
}
var foo = Foo()
foo.test()
Even in this case, if you do your weekSelections initialisation in an initialiser, then it works:
即使在这种情况下,如果您在初始化器中进行了weekSelections初始化,那么它的工作原理如下:
class Foo : NSObject {
var weekSelections: Array<Bool>!
init() {
weekSelections = Array<Bool>(count: 10, repeatedValue: false)
weekSelections[0] = true;
println(weekSelections[0]) // Prints "true"
}
}
var foo = Foo()
Personally, I'd say that this is a bug. I can't see anything in any documentation that would explain the difference in behaviour when derived from NSObject.
就个人而言,我会说这是一个错误。我无法在任何文档中看到任何可以解释从NSObject派生的行为差异的内容。
I also can't see anything that says that optional array properties would be immutable. This would be especially strange when you consider that "immutable" arrays are actually mutable in Swift, i.e. this:
我也看不到任何说可选数组属性是不可变的。当你认为“不可变”数组在Swift中实际上是可变的时,这会特别奇怪,即:
// Use "let" to declare an "immutable" array
let weekSelections = Array<Bool>(count: 10, repeatedValue: false)
weekSelections[0] = true;
println(weekSelections[0]); // Prints "true"; arrays are never really "immutable" in Swift
...works fine, and is currently documented as being valid, even if it seems a bit odd.
...工作正常,并且目前被记录为有效,即使它看起来有点奇怪。
Personally, I'd use whatever workaround you can and raise a bug with Apple, to see what light they can shed.
就个人而言,我会使用任何可行的解决方法,并向Apple提出一个错误,看看它们可以摆脱什么样的光。
#2
0
Not an explanation, but a workaround. The issue isn't with the count:repeatedValue
initializer, but rather with the array being assigned to an optional variable. From what I can tell optional arrays can only use accessor methods and not mutator methods--effectively they're immutable. Temporarily assigning _weekSelections
to a non-optional variable before attempting to change its contents (and assigning back to _weekSelections
when done) will work. Please note that this seems to create a new array (with the same elements) on assignments, so there may be memory issues to consider if the array is very big. Of course, simply using a non-optional variable in the first place will also work.
不是解释,而是解决方法。问题不在于count:repeatedValue初始化程序,而是将数组分配给可选变量。据我所知,可选数组只能使用访问器方法而不是mutator方法 - 实际上它们是不可变的。在尝试更改其内容(并在完成时分配回_weekSelections)之前暂时将_weekSelections分配给非可选变量将起作用。请注意,这似乎在赋值时创建了一个新数组(具有相同的元素),因此如果数组非常大,可能会考虑内存问题。当然,首先简单地使用非可选变量也是有效的。
As for why optional arrays aren't mutable, that may be a bug or there may be some esoteric reason for it I'm not fathoming. Anyone else have a plausible-sounding theory?
至于为什么可选数组不可变,这可能是一个错误,或者可能有一些深奥的原因,我不是很了解。其他人有一个看似合理的理论吗?
#1
2
For the sake of having my code on SO rather than Pastebin, here's my observation. This looks like some kind of bug or unexpected behaviour when using an optional array in a Swift class derived from an Objective C class. If you use a plain Swift class, this works as expected:
为了让我的代码在SO而不是Pastebin上,这是我的观察。当在从Objective C类派生的Swift类中使用可选数组时,这看起来像某种错误或意外行为。如果您使用普通的Swift类,这可以按预期工作:
class Foo {
var weekSelections: Array<Bool>!
func test() {
weekSelections = Array<Bool>(count: 10, repeatedValue: false)
weekSelections[0] = true;
println(weekSelections[0]) // Prints "true"
}
}
var foo = Foo()
foo.test()
However, if you derive Foo from NSObject:
但是,如果从NSObject派生Foo:
import Foundation
class Foo : NSObject { // This derivation is the only difference from the code above
var weekSelections: Array<Bool>!
func test() {
weekSelections = Array<Bool>(count: 10, repeatedValue: false)
weekSelections[0] = true;
println(weekSelections[0]) // Prints "false"
}
}
var foo = Foo()
foo.test()
Even in this case, if you do your weekSelections initialisation in an initialiser, then it works:
即使在这种情况下,如果您在初始化器中进行了weekSelections初始化,那么它的工作原理如下:
class Foo : NSObject {
var weekSelections: Array<Bool>!
init() {
weekSelections = Array<Bool>(count: 10, repeatedValue: false)
weekSelections[0] = true;
println(weekSelections[0]) // Prints "true"
}
}
var foo = Foo()
Personally, I'd say that this is a bug. I can't see anything in any documentation that would explain the difference in behaviour when derived from NSObject.
就个人而言,我会说这是一个错误。我无法在任何文档中看到任何可以解释从NSObject派生的行为差异的内容。
I also can't see anything that says that optional array properties would be immutable. This would be especially strange when you consider that "immutable" arrays are actually mutable in Swift, i.e. this:
我也看不到任何说可选数组属性是不可变的。当你认为“不可变”数组在Swift中实际上是可变的时,这会特别奇怪,即:
// Use "let" to declare an "immutable" array
let weekSelections = Array<Bool>(count: 10, repeatedValue: false)
weekSelections[0] = true;
println(weekSelections[0]); // Prints "true"; arrays are never really "immutable" in Swift
...works fine, and is currently documented as being valid, even if it seems a bit odd.
...工作正常,并且目前被记录为有效,即使它看起来有点奇怪。
Personally, I'd use whatever workaround you can and raise a bug with Apple, to see what light they can shed.
就个人而言,我会使用任何可行的解决方法,并向Apple提出一个错误,看看它们可以摆脱什么样的光。
#2
0
Not an explanation, but a workaround. The issue isn't with the count:repeatedValue
initializer, but rather with the array being assigned to an optional variable. From what I can tell optional arrays can only use accessor methods and not mutator methods--effectively they're immutable. Temporarily assigning _weekSelections
to a non-optional variable before attempting to change its contents (and assigning back to _weekSelections
when done) will work. Please note that this seems to create a new array (with the same elements) on assignments, so there may be memory issues to consider if the array is very big. Of course, simply using a non-optional variable in the first place will also work.
不是解释,而是解决方法。问题不在于count:repeatedValue初始化程序,而是将数组分配给可选变量。据我所知,可选数组只能使用访问器方法而不是mutator方法 - 实际上它们是不可变的。在尝试更改其内容(并在完成时分配回_weekSelections)之前暂时将_weekSelections分配给非可选变量将起作用。请注意,这似乎在赋值时创建了一个新数组(具有相同的元素),因此如果数组非常大,可能会考虑内存问题。当然,首先简单地使用非可选变量也是有效的。
As for why optional arrays aren't mutable, that may be a bug or there may be some esoteric reason for it I'm not fathoming. Anyone else have a plausible-sounding theory?
至于为什么可选数组不可变,这可能是一个错误,或者可能有一些深奥的原因,我不是很了解。其他人有一个看似合理的理论吗?