Arrays de comprimento fixo ainda não são suportados. O que isso realmente significa? Não que você não possa criar uma matriz de n
muitas coisas - obviamente, você pode apenas fazer let a = [ 1, 2, 3 ]
para obter uma matriz de três Int
s. Significa simplesmente que o tamanho do array não é algo que você possa declarar como informação de tipo .
Se você quiser um array de nil
s, você primeiro precisará de um array de um tipo opcional - [SKSpriteNode?]
, não [SKSpriteNode]
- se você declarar uma variável de tipo não opcional, seja um array ou um único valor, não pode ser nil
. (Observe também que [SKSpriteNode?]
é diferente de [SKSpriteNode]?
... você deseja uma matriz de opcionais, não uma matriz opcional.)
O Swift é muito explícito por design sobre como exigir que as variáveis sejam inicializadas, porque as suposições sobre o conteúdo das referências não inicializadas são uma das maneiras pelas quais os programas em C (e algumas outras linguagens) podem se tornar problemáticos. Portanto, você precisa pedir explicitamente uma [SKSpriteNode?]
matriz que contenha 64 nil
s:
var sprites = [SKSpriteNode?](repeating: nil, count: 64)
Na verdade, isso retorna um [SKSpriteNode?]?
, porém: uma matriz opcional de sprites opcionais. (Um pouco estranho, já init(count:,repeatedValue:)
que não deve ser capaz de retornar nil.) Para trabalhar com a matriz, você precisará desembrulhá-la. Existem algumas maneiras de fazer isso, mas, neste caso, prefiro a sintaxe de ligação opcional:
if var sprites = [SKSpriteNode?](repeating: nil, count: 64){
sprites[0] = pawnSprite
}
sprites
em seu editor / playground para ver seu tipo inferido - na verdade éSKSpriteNode?[]?
: um array opcional de sprites opcionais. Você não pode subscrever um opcional, então você tem que desembrulhá-lo ... veja a resposta editada.O melhor que você poderá fazer agora é criar uma matriz com uma contagem inicial repetindo nulo:
Você pode então preencher os valores que desejar.
Em Swift 3.0 :
fonte
Esta pergunta já foi respondida, mas para algumas informações extras no momento do Swift 4:
Em caso de desempenho, deve-se reservar memória para o array, no caso de criá-lo dinamicamente, como adicionar elementos com
Array.append()
.Se você sabe a quantidade mínima de elementos que vai adicionar, mas não a quantidade máxima, você deve usar
array.reserveCapacity(minimumCapacity: 64)
.fonte
Declare um SKSpriteNode vazio, para que não haja necessidade de desempacotamento
fonte
Por enquanto, semanticamente mais próximo seria uma tupla com número fixo de elementos.
Mas isso é (1) muito desconfortável de usar e (2) o layout da memória é indefinido. (pelo menos desconhecido para mim)
fonte
Swift 4
Você pode pensar nisso de alguma forma como uma matriz de objetos versus uma matriz de referências.
[SKSpriteNode]
deve conter objetos reais[SKSpriteNode?]
pode conter referências a objetos ounil
Exemplos
Criação de uma matriz com 64 padrão
SKSpriteNode
:Criação de uma matriz com 64 slots vazios (também conhecidos como opcionais ):
Convertendo uma matriz de opcionais em uma matriz de objetos (recolhendo
[SKSpriteNode?]
em[SKSpriteNode]
):O
count
resultado do resultadoflatSprites
depende da contagem de objetos emoptionalSprites
: opcionais vazios serão ignorados, ou seja, ignorados.fonte
flatMap
está obsoleto, deve ser atualizado para,compactMap
se possível. (Não consigo editar esta resposta)Se o que você deseja é um array de tamanho fixo e inicializa-o com
nil
valores, você pode usar umUnsafeMutableBufferPointer
, alocar memória para 64 nós com ele e, em seguida, ler / gravar de / para a memória subscrevendo a instância do tipo de ponteiro. Isso também tem a vantagem de evitar verificar se a memória deve ser realocada, o que éArray
verdade. No entanto, ficaria surpreso se o compilador não otimizasse isso para matrizes que não têm mais chamadas para métodos que podem exigir redimensionamento, exceto no local de criação.No entanto, isso não é muito amigável. Então, vamos fazer um invólucro!
Agora, esta é uma classe, não uma estrutura, portanto, há alguma sobrecarga de contagem de referência incorrida aqui. Você pode alterá-lo para um
struct
, mas como o Swift não oferece a capacidade de usar inicializadores de cópia edeinit
em estruturas, você precisará de um método de desalocação (func release() { memory.deallocate() }
) e todas as instâncias copiadas da estrutura farão referência à mesma memória.Agora, essa aula pode ser boa o suficiente. Seu uso é simples:
Para obter mais protocolos para implementar a conformidade, consulte a documentação do Array (role até Relacionamentos ).
fonte
Uma coisa que você poderia fazer seria criar um dicionário. Pode ser um pouco desleixado, considerando que você está procurando 64 elementos, mas dá conta do recado. Não tenho certeza se é a "maneira preferida" de fazer isso, mas funcionou para mim usando uma série de estruturas.
fonte
tasks[65] = foo
neste caso e no caso de um array da questão.