Swift可选的Array属性是不可变的?

时间:2014-06-25 14:21:47

标签: arrays swift immutability optional

我正在构造一个布尔数组,用于在UICollectionView中存储节的状态。它是一个存储为我的UIViewController属性的变量:

var _weekSelections : Array<Bool>!

然后,在loadView()调用的函数中,构造数组并为第一个索引赋值:

_weekSelections = Array<Bool>(count:_weekCount, repeatedValue:false)
_weekSelections[0] = true

索引0处的值仍为false!数组是构造的,并且有多个元素,但是我对索引的任何赋值都不会影响存储在该索引处的值,即使我检查下一行代码的值。我知道如果我执行一个可能会改变其长度的动作,Swift会制作一个数组的副本,但我不认为这是我制作副本的情况。我可以获得任何值更改的唯一方法是我手动创建副本如下:

var copy = _weekSelections
copy[0] = true
_weekSelections = copy

我错过了一些明显的东西,或者这可能是一个奇怪的错误吗?

2 个答案:

答案 0 :(得分:2)

为了让我的代码在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()

但是,如果从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()

即使在这种情况下,如果您在初始化程序中进行了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()

就个人而言,我说这是一个错误。我无法在任何文档中看到任何可以解释从NSObject派生时行为差异的内容。

我也看不到任何说可选数组属性是不可变的。当你考虑到&#34; immutable&#34;时,这将特别奇怪。数组在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

...工作正常,目前记录为有效,即使它看起来有点奇怪。

就个人而言,我会使用任何可行的解决方法,并向Apple提出一个错误,看看他们可以摆脱什么样的光。

答案 1 :(得分:0)

不是解释,而是解决方法。问题不在于count:repeatedValue初始值设定项,而在于将数组分配给可选变量。从我可以看出,可选数组只能使用访问器方法而不是mutator方法 - 实际上它们是不可变的。在尝试更改其内容之前暂时将_weekSelections分配给非可选变量(并在完成后分配回_weekSelections)将起作用。请注意,这似乎在赋值时创建了一个新数组(具有相同的元素),因此如果数组非常大,可能会考虑内存问题。当然,首先只使用非可选变量也可以。

至于为什么可选数组不可变,这可能是一个错误,或者可能有一些深奥的原因,我不是很了解。其他人有一个看似合理的理论吗?