Свойство SWIFT optional Array является неизменяемым?

Я создаю массив логических значений для хранения состояния разделов в UICollectionView. Это переменная, хранящаяся как свойство моего UIViewController:

var _weekSelections : Array<Bool>!

затем в функции, вызванной loadView (), я строю массив и присваиваю значение первому индексу:

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

значение в индексе 0 остается ложным! Массив построен и имеет несколько элементов, но любое назначение, которое я делаю индексу, не влияет на значение, хранящееся в этот индекс, даже если я проверю значение в следующей строке кода. Я знаю, что Swift делает копию массива, если я выполняю действие, которое может изменить его длину, но я не думаю, что это тот случай, когда копия будет сделана мной. Единственный способ изменить значение-вручную создать копию следующим образом:

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

я пропустил что-то очевидное или это может быть странная ошибка?

2 ответов


ради того, чтобы мой код был на SO, а не на Pastebin, вот мое наблюдение. Это похоже на ошибку или неожиданное поведение при использовании необязательного массива в классе Swift, производном от класса Objective C. Если вы используете простой класс 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()

однако, если вы производите Foo от 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()

даже в этом случае, если вы делаете инициализацию 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.

Я также не вижу ничего, что говорит о том, что дополнительные свойства массива будут неизменяемыми. Это было бы особенно странно, если учесть, что" неизменяемые " массивы фактически изменчивы в 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, чтобы увидеть, какой свет они могут пролить.


не объяснение, а обходной путь. Проблема не в count:repeatedValue инициализатор, но скорее с массивом, назначенным необязательной переменной. Из того, что я могу сказать, необязательные массивы могут использовать только методы доступа, а не методы мутатора-фактически они неизменяемы. Временное назначение _weekSelections к необязательной переменной перед попыткой изменить ее содержимое (и присвоить обратно _weekSelections когда закончите) будет работать. Обратите внимание, что это, похоже, создает новый массив (с те же элементы) при назначениях, поэтому могут возникнуть проблемы с памятью, если массив очень большой. Конечно, простое использование необязательной переменной в первую очередь также будет работать.

что касается того, почему необязательные массивы не изменяемы, это может быть ошибка или может быть какая-то эзотерическая причина для этого, я не понимаю. У кого-нибудь еще есть правдоподобная теория?