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:
var _weekSelections : Array<Bool>!
Then, in a function called by loadView(), I construct the array and assign a value to the first index:
_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:
var copy = _weekSelections
copy[0] = true
_weekSelections = copy
Am I missing something obvious or could this be a strange bug?
If you assign an array, a set, or a dictionary to a constant, that collection is immutable, and its size and contents can't be changed.
To check if an element is in an array in Swift, use the Array. contains() function.
Difference between an Array and Set in Swift Array is faster than set in terms of initialization. Set is slower than an array in terms of initialization because it uses a hash process. The array allows storing duplicate elements in it. Set doesn't allow you to store duplicate elements in it.
It is important to note that, while creating an empty array, we must specify the data type inside the square bracket [] followed by an initializer syntax () . Here, [Int]() specifies that the empty array can only store integer data elements. Note: In Swift, we can create arrays of any data type like Int , String , etc.
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:
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:
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:
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.
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:
// 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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With