Arrays mit fester Länge werden noch nicht unterstützt. Was bedeutet das eigentlich? Nicht, dass Sie nicht n
viele verschiedene Dinge erstellen können - natürlich können Sie nur let a = [ 1, 2, 3 ]
ein Array von drei Int
Sekunden erstellen . Es bedeutet einfach , dass Array - Größe ist nicht etwas , dass Sie erklären können als Typinformationen .
Wenn Sie ein Array von nil
s möchten , benötigen Sie zunächst ein Array eines optionalen Typs - [SKSpriteNode?]
nicht [SKSpriteNode]
-, wenn Sie eine Variable vom nicht optionalen Typ deklarieren, unabhängig davon, ob es sich um ein Array oder einen einzelnen Wert handelt, kann dies nicht der Fall sein nil
. (Beachten Sie auch, dass dies [SKSpriteNode?]
anders ist als [SKSpriteNode]?
... Sie möchten ein Array von Optionen, kein optionales Array.)
Swift ist von Natur aus sehr explizit in Bezug auf die Anforderung, dass Variablen initialisiert werden müssen, da Annahmen über den Inhalt nicht initialisierter Referenzen eine der Möglichkeiten sind, wie Programme in C (und einigen anderen Sprachen) fehlerhaft werden können. Sie müssen also explizit nach einem [SKSpriteNode?]
Array fragen , das 64 nil
s enthält :
var sprites = [SKSpriteNode?](repeating: nil, count: 64)
Dies gibt jedoch tatsächlich Folgendes zurück [SKSpriteNode?]?
: ein optionales Array optionaler Sprites. (Ein bisschen seltsam, da init(count:,repeatedValue:)
es nicht möglich sein sollte, null zurückzugeben.) Um mit dem Array zu arbeiten, müssen Sie es auspacken. Es gibt einige Möglichkeiten, dies zu tun, aber in diesem Fall würde ich die optionale Bindungssyntax bevorzugen:
if var sprites = [SKSpriteNode?](repeating: nil, count: 64){
sprites[0] = pawnSprite
}
sprites
Sie mit der Befehlstaste in Ihren Editor / Spielplatz, um den abgeleiteten Typ anzuzeigen - es handelt sich tatsächlich umSKSpriteNode?[]?
ein optionales Array optionaler Sprites. Sie können eine Option nicht abonnieren, daher müssen Sie sie auspacken ... siehe bearbeitete Antwort.Das Beste, was Sie jetzt tun können, ist, ein Array mit einer Anfangszählung zu erstellen, die Null wiederholt:
Sie können dann beliebige Werte eingeben.
In Swift 3.0 :
quelle
Diese Frage wurde bereits beantwortet, aber für einige zusätzliche Informationen zum Zeitpunkt von Swift 4:
Im Falle einer Leistung sollten Sie Speicher für das Array reservieren, wenn Sie es dynamisch erstellen, z. B. indem Sie Elemente mit hinzufügen
Array.append()
.Wenn Sie die minimale Anzahl von Elementen kennen, die Sie hinzufügen, aber nicht die maximale Anzahl, sollten Sie lieber verwenden
array.reserveCapacity(minimumCapacity: 64)
.quelle
Deklarieren Sie einen leeren SKSpriteNode, damit das Auspacken nicht erforderlich ist
quelle
Semantisch am nächsten wäre vorerst ein Tupel mit einer festen Anzahl von Elementen.
Dies ist jedoch (1) sehr unangenehm zu verwenden und (2) das Speicherlayout ist undefiniert. (zumindest mir unbekannt)
quelle
Swift 4
Sie können es sich als Array von Objekten oder als Array von Referenzen vorstellen.
[SKSpriteNode]
muss tatsächliche Objekte enthalten[SKSpriteNode?]
kann entweder Verweise auf Objekte enthalten odernil
Beispiele
Erstellen eines Arrays mit 64 Standardwerten
SKSpriteNode
:Erstellen eines Arrays mit 64 leeren Slots (auch als Optional bezeichnet ):
Konvertieren eines Arrays von Optionen in ein Array von Objekten (Reduzieren
[SKSpriteNode?]
in[SKSpriteNode]
):Das
count
ErgebnisflatSprites
hängt von der Anzahl der Objekte in aboptionalSprites
: Leere Optionen werden ignoriert, dh übersprungen.quelle
flatMap
veraltet ist, sollte es nachcompactMap
Möglichkeit aktualisiert werden. (Ich kann diese Antwort nicht bearbeiten)Wenn Sie ein Array mit fester Größe wünschen und es mit
nil
Werten initialisieren möchten, können Sie ein Array mitUnsafeMutableBufferPointer
64 Knoten damit zuweisen und dann durch Abonnieren der Zeigertypinstanz aus / in den Speicher lesen / schreiben. Dies hat auch den Vorteil, dass nicht überprüft werden muss, ob der Speicher neu zugewiesen werdenArray
muss. Es würde mich jedoch wundern, wenn der Compiler dies nicht für Arrays optimiert, die keine weiteren Aufrufe von Methoden haben, deren Größe möglicherweise geändert werden muss, außer am Erstellungsort.Dies ist jedoch nicht sehr benutzerfreundlich. Also, machen wir einen Wrapper!
Dies ist eine Klasse und keine Struktur, daher fallen hier einige Referenzkosten an. Sie können es
struct
stattdessen in a ändern. Da Swift Ihnen jedoch nicht die Möglichkeit bietet, Kopierinitialisierer unddeinit
Strukturen zu verwenden, benötigen Sie eine Freigabemethode (func release() { memory.deallocate() }
), und alle kopierten Instanzen der Struktur verweisen auf denselben Speicher.Nun, diese Klasse kann gerade gut genug sein. Die Verwendung ist einfach:
Weitere Protokolle zur Implementierung der Konformität finden Sie in der Array-Dokumentation (scrollen Sie zu Beziehungen ).
quelle
Eine Sache, die Sie tun könnten, wäre, ein Wörterbuch zu erstellen. Könnte ein wenig schlampig sein, wenn man bedenkt, dass man nach 64 Elementen sucht, aber es erledigt den Job. Ich bin mir nicht sicher, ob es der "bevorzugte Weg" ist, aber es hat bei mir mit einem Array von Strukturen funktioniert.
quelle
tasks[65] = foo
sowohl in diesem Fall als auch im Fall eines Arrays aus der Frage sehr gut einen machen .