У меня есть следующий массив:
var shoes = Array(repeating: ShoeInfo(), count: 80)
Где ShoeInfo
определяется следующим образом:
class ShoeInfo {
var expressionOn: Bool?
var volumeControl: Bool?
var channel: Int?
}
У меня есть for
цикл:
for i in 0..<16 {
if cond {
shoeArray[i].expressionOn = true
} else {
shoeArray[i].expressionOn = false
}
}
По сути, последнее значение, присвоенное в цикле for
, становится значением для каждого экземпляра класса в массиве shoes
!
Я явно этого не хочу. Кто-нибудь знает, как это исправить?
2 ответа
Что случилось
Вы сделали только один экземпляр. Затем вы создали массив, содержащий 80 ссылок на этот единственный экземпляр. Убедитесь сами, попробуйте:
for shoe in shoes {
print(ObjectIdentifier(shoe))
}
Вы увидите, что все ссылки указывают на единственный объект.
Что вы, вероятно, ищете
Это:
let shoes = (0..<80).map { _ in ShoeInfo() }
Вызов map
вызовет закрытие один раз для каждого из 80 целых чисел в диапазоне 0..<80
, что вызовет создание 80 различных объектов обуви.
Полезный фон
Array(repeating:_count:_)
принимает свои параметры по значению (обратите внимание, что нет inout
). Таким образом, когда вы его вызываете, все, что вы передаете в качестве аргумента для параметра repeating
, копируется.
Для классов «копирование» влечет за собой создание новых ссылок на тот же самый объект, выделенный в куче. Он также обычно сохраняется в процессе (увеличивая количество ссылок на единицу), но здесь это не важно. Таким образом, когда вы вызывали Array(repeating: ShoeInfo(), count: 80)
, был создан только один экземпляр ShoeInfo
, и затем код скопировал его 80 раз, то есть он сделал 80 скопированных ссылок на один и тот же экземпляр.
Для структур "копирование" влечет за собой их полное копирование по частям. Когда вы попробуете Array(repeating: ShoeInfoAsAStruct(), count: 80)
, вы создадите один ShoeInfoAsAStruct()
, который затем будет скопирован в каждый из 80 слотов массива, в результате чего получится 80 полных копий. В итоге вы получаете 80 отдельных копий, каждую из которых вы можете редактировать отдельно. Вот почему переключение на struct
сработало.
Я решил это, изменив класс shoeInfo на структуру shoeInfo.
Однако не уверен в точном объяснении.
Похожие вопросы
Связанные вопросы
Новые вопросы
swift
Swift - это безопасный, быстрый и выразительный язык программирования общего назначения, разработанный Apple Inc. для своих платформ и Linux. Swift с открытым исходным кодом. Используйте тег только для вопросов о языковых функциях или необходимости кода в Swift. Используйте теги [ios], [ipados], [macos], [watch-os], [tvos], [cocoa-touch] и [cocoa] для (не зависящих от языка) вопросов о платформах или фреймворках.