Comment créer un tableau d’objects de taille fixe

Dans Swift, j’essaie de créer un tableau de 64 SKSpriteNode. Je veux d’abord l’initialiser vide, puis je placerais les Sprites dans les 16 premières cellules et les 16 dernières cellules (simulant un jeu d’échecs).

D’après ce que j’ai compris dans le doc, je m’attendrais à quelque chose comme:

var sprites = SKSpriteNode()[64];

ou

var sprites4 : SKSpriteNode[64];

Mais ça ne marche pas. Dans le second cas, je reçois une erreur indiquant: “Les baies de longueur fixe ne sont pas encore sockets en charge”. Est-ce que cela peut être réel? Pour moi, cela ressemble à une fonctionnalité de base. J’ai besoin d’accéder à l’élément directement par leur index.

Les baies de longueur fixe ne sont pas encore sockets en charge. Qu’est-ce que cela signifie réellement? Non pas que vous ne puissiez pas créer un tableau de beaucoup de choses – évidemment, vous pouvez simplement let a = [ 1, 2, 3 ] pour obtenir un tableau de trois Int . Cela signifie simplement que la taille du tableau n’est pas quelque chose que vous pouvez déclarer comme informations de type .

Si vous voulez un tableau de nil s, vous aurez d’abord besoin d’un tableau d’un type facultatif – [SKSpriteNode?] , Pas de [SKSpriteNode] – si vous déclarez une variable de type non optionnel, que ce soit un tableau ou une valeur unique , il ne peut pas être nil . (Notez également que [SKSpriteNode?] Est différent de [SKSpriteNode]? … vous voulez un tableau d’optionals, pas un tableau facultatif.)

Swift est très explicite dans sa conception pour exiger que les variables soient initialisées, car les hypothèses sur le contenu des références non initialisées sont l’une des manières dont les programmes en C (et certains autres langages) peuvent devenir bogués. Donc, vous devez explicitement demander un [SKSpriteNode?] 64 nil s:

 var sprites = [SKSpriteNode?](repeating: nil, count: 64) 

Cela retourne en fait un [SKSpriteNode?]? , cependant: un tableau facultatif de sprites facultatifs. (Un peu bizarre, car init(count:,repeatedValue:) ne devrait pas pouvoir renvoyer zéro.) Pour travailler avec le tableau, vous devrez le déballer. Il y a plusieurs façons de le faire, mais dans ce cas, je privilégierais la syntaxe de liaison facultative:

 if var sprites = [SKSpriteNode?](repeating: nil, count: 64){ sprites[0] = pawnSprite } 

Le mieux que vous puissiez faire pour le moment est de créer un tableau avec un compte initial répétant zéro:

 var sprites = [SKSpriteNode?](count: 64, repeatedValue: nil) 

Vous pouvez alors remplir les valeurs que vous voulez.


Dans Swift 3.0 :

 var sprites = [SKSpriteNode?](repeating: nil, count: 64) 

Déclarez un SKSpriteNode vide pour qu’il ne soit plus nécessaire de dérouler

 var sprites = [SKSpriteNode](count: 64, repeatedValue: SKSpriteNode()) 

Pour l’instant, le plus proche sémantiquement serait un tuple avec un nombre fixe d’éléments.

 typealias buffer = ( SKSpriteNode, SKSpriteNode, SKSpriteNode, SKSpriteNode, SKSpriteNode, SKSpriteNode, SKSpriteNode, SKSpriteNode, SKSpriteNode, SKSpriteNode, SKSpriteNode, SKSpriteNode, SKSpriteNode, SKSpriteNode, SKSpriteNode, SKSpriteNode, SKSpriteNode, SKSpriteNode, SKSpriteNode, SKSpriteNode, SKSpriteNode, SKSpriteNode, SKSpriteNode, SKSpriteNode, SKSpriteNode, SKSpriteNode, SKSpriteNode, SKSpriteNode, SKSpriteNode, SKSpriteNode, SKSpriteNode, SKSpriteNode, SKSpriteNode, SKSpriteNode, SKSpriteNode, SKSpriteNode, SKSpriteNode, SKSpriteNode, SKSpriteNode, SKSpriteNode, SKSpriteNode, SKSpriteNode, SKSpriteNode, SKSpriteNode, SKSpriteNode, SKSpriteNode, SKSpriteNode, SKSpriteNode, SKSpriteNode, SKSpriteNode, SKSpriteNode, SKSpriteNode, SKSpriteNode, SKSpriteNode, SKSpriteNode, SKSpriteNode, SKSpriteNode, SKSpriteNode, SKSpriteNode, SKSpriteNode, SKSpriteNode, SKSpriteNode, SKSpriteNode, SKSpriteNode) 

Mais ceci est (1) très inconfortable à utiliser et (2) la disposition de la mémoire est indéfinie. (au moins inconnu pour moi)

Swift 4

Vous pouvez y penser un peu comme un object ou un tableau de références.

  • [SKSpriteNode] doit contenir des objects réels
  • [SKSpriteNode?] Peut contenir des références à des objects, ou nil

Exemples

  1. Créer un tableau avec 64 SKSpriteNode par défaut :

     var sprites = [SKSpriteNode](repeatElement(SKSpriteNode(texture: nil), count: 64)) 
  2. Créer un tableau avec 64 emplacements vides (aussi appelés optionnels ):

     var optionalSprites = [SKSpriteNode?](repeatElement(nil, count: 64)) 
  3. Convertir un tableau d’options en un tableau d’objects ( [SKSpriteNode?] [SKSpriteNode] ):

     let flatSprites = optionalSprites.flatMap { $0 } 

    Le count de flatSprites dépend du nombre d’objects dans optionalSprites : les options facultatives vides seront ignorées, c’est-à-dire ignorées.

On a déjà répondu à cette question, mais pour des informations supplémentaires au moment de Swift 4:

En cas de performance, vous devez réserver de la mémoire pour le tableau, en cas de création dynamic, par exemple en ajoutant des éléments avec Array.append() .

 var array = [SKSpriteNode]() array.reserveCapacity(64) for _ in 0..<64 { array.append(SKSpriteNode()) } 

Si vous connaissez la quantité minimale d'éléments à append, mais pas la quantité maximale, vous devriez plutôt utiliser array.reserveCapacity(minimumCapacity: 64) .

Une chose que vous pourriez faire serait de créer un dictionnaire. Peut-être un peu négligé compte tenu de votre recherche de 64 éléments, mais le travail est fait. Je ne suis pas sûr si c’est la “façon préférée” de le faire, mais cela a fonctionné pour moi en utilisant un tableau de structures.

 var tasks = [0:[forTasks](),1:[forTasks](),2:[forTasks](),3:[forTasks](),4:[forTasks](),5:[forTasks](),6:[forTasks]()]