Массивы фиксированной длины пока не поддерживаются. Что это на самом деле означает? Не то чтобы вы не могли создать массив из n
многих вещей - очевидно, вы можете просто сделать, let a = [ 1, 2, 3 ]
чтобы получить массив из трех Int
s. Это просто означает, что размер массива не является чем-то, что вы можете объявить как информацию о типе .
Если вам нужен массив nil
s, вам сначала понадобится массив необязательного типа - [SKSpriteNode?]
, а не [SKSpriteNode]
- если вы объявляете переменную необязательного типа, будь то массив или одно значение, этого не может быть nil
. (Также обратите внимание, что [SKSpriteNode?]
это отличается от [SKSpriteNode]?
... вам нужен массив дополнительных элементов, а не дополнительный массив.)
Swift очень явно требует инициализации переменных, потому что предположения о содержании неинициализированных ссылок - один из способов, с помощью которых программы на C (и некоторых других языках) могут вызывать ошибки. Итак, вам нужно явно запросить [SKSpriteNode?]
массив, содержащий 64 nil
с:
var sprites = [SKSpriteNode?](repeating: nil, count: 64)
На самом деле это возвращает a [SKSpriteNode?]?
: необязательный массив необязательных спрайтов. (Немного странно, так как init(count:,repeatedValue:)
не должно возвращать nil.) Для работы с массивом вам нужно его развернуть. Есть несколько способов сделать это, но в данном случае я бы предпочел необязательный синтаксис привязки:
if var sprites = [SKSpriteNode?](repeating: nil, count: 64){
sprites[0] = pawnSprite
}
sprites
в редакторе / игровой площадке, чтобы увидеть его предполагаемый тип - на самом делеSKSpriteNode?[]?
это необязательный массив необязательных спрайтов. Вы не можете подписать необязательный индекс, поэтому вам нужно его развернуть ... см. Отредактированный ответ.Лучшее, что вы можете сделать сейчас, - это создать массив с начальным счетчиком, повторяющим ноль:
Затем вы можете ввести любые значения, которые хотите.
В Swift 3.0 :
источник
На этот вопрос уже был дан ответ, но для получения дополнительной информации во время Swift 4:
В случае производительности следует зарезервировать память для массива, в случае его динамического создания, например добавления элементов с помощью
Array.append()
.Если вы знаете минимальное количество элементов, которое вы добавите к нему, но не максимальное количество, вам лучше использовать
array.reserveCapacity(minimumCapacity: 64)
.источник
Объявите пустой SKSpriteNode, чтобы не было необходимости в разворачивании
источник
На данный момент семантически наиболее близким будет кортеж с фиксированным количеством элементов.
Но это (1) очень неудобно в использовании и (2) структура памяти не определена. (по крайней мере, мне неизвестно)
источник
Swift 4
Вы можете думать об этом как о массиве объектов и массивов ссылок.
[SKSpriteNode]
должен содержать реальные объекты[SKSpriteNode?]
может содержать либо ссылки на объекты, либоnil
Примеры
Создание массива с 64 по умолчанию
SKSpriteNode
:Создание массива с 64 пустыми слотами (также известными как опции ):
Преобразование массива опций в массив объектов (сворачивание
[SKSpriteNode?]
в[SKSpriteNode]
):count
Из получившихсяflatSprites
зависит от кол - объектовoptionalSprites
: пустые опции будут игнорироваться, то есть пропускается.источник
flatMap
устарел, его следует по возможности обновить доcompactMap
. (Я не могу редактировать этот ответ)Если вам нужен массив фиксированного размера и инициализировать его
nil
значениями, вы можете использоватьUnsafeMutableBufferPointer
, выделить с его помощью память для 64 узлов, а затем читать / писать из / в память, указав индекс экземпляра типа указателя. Это также позволяет избежать проверки необходимости перераспределения памяти, а этоArray
действительно так. Однако я был бы удивлен, если компилятор не оптимизирует это для массивов, у которых больше нет вызовов методов, которые могут потребовать изменения размера, кроме как на сайте создания.Однако это не очень удобно для пользователя. Итак, сделаем обертку!
Теперь это класс, а не структура, поэтому здесь возникают некоторые накладные расходы на подсчет ссылок.
struct
Вместо этого вы можете изменить его на a , но поскольку Swift не предоставляет вам возможности использовать инициализаторы копирования иdeinit
структуры, вам понадобится метод освобождения (func release() { memory.deallocate() }
), и все скопированные экземпляры структуры будут ссылаться на одну и ту же память.Теперь этого класса может быть достаточно. Его использование простое:
Дополнительные протоколы для реализации соответствия см. В документации по массивам (перейдите к разделу « Связи» ).
источник
Вы могли бы создать словарь. Может быть, это немного небрежно, учитывая, что вы ищете 64 элемента, но он выполняет свою работу. Я не уверен, что это «предпочтительный способ» сделать это, но у меня он работал с использованием массива структур.
источник
tasks[65] = foo
как в этом случае, так и в случае массива из вопроса.