Tablice o stałej długości nie są jeszcze obsługiwane. Co to właściwie oznacza? Nie n
znaczy let a = [ 1, 2, 3 ]
to, że nie możesz utworzyć tablicy wielu rzeczy - oczywiście możesz po prostu zrobić, aby uzyskać tablicę trzech Int
sekund. Oznacza to po prostu, że rozmiar tablicy nie jest czymś, co można zadeklarować jako informację o typie .
Jeśli chcesz mieć tablicę nil
s, najpierw będziesz potrzebować tablicy typu opcjonalnego - a [SKSpriteNode?]
nie [SKSpriteNode]
- jeśli deklarujesz zmienną typu nie opcjonalnego, niezależnie od tego, czy jest to tablica, czy pojedyncza wartość, nie może być nil
. (Zauważ też, że [SKSpriteNode?]
różni się od [SKSpriteNode]?
... potrzebujesz tablicy opcji, a nie opcjonalnej tablicy).
Swift z założenia bardzo wyraźnie mówi o wymaganiu inicjalizacji zmiennych, ponieważ założenia dotyczące zawartości niezainicjowanych referencji są jednym ze sposobów, w jakie programy w C (i niektórych innych językach) mogą stać się błędne. Musisz więc jawnie poprosić o [SKSpriteNode?]
tablicę zawierającą 64 nil
s:
var sprites = [SKSpriteNode?](repeating: nil, count: 64)
W rzeczywistości zwraca to [SKSpriteNode?]?
jednak: opcjonalną tablicę opcjonalnych sprite'ów. (Trochę dziwne, ponieważ init(count:,repeatedValue:)
nie powinno być w stanie zwrócić nil). Aby pracować z tablicą, musisz ją rozpakować. Jest na to kilka sposobów, ale w tym przypadku wolałbym opcjonalną składnię powiązań:
if var sprites = [SKSpriteNode?](repeating: nil, count: 64){
sprites[0] = pawnSprite
}
sprites
w swoim edytorze / placu zabaw, aby zobaczyć jego wywnioskowany typ - w rzeczywistości jest toSKSpriteNode?[]?
: opcjonalna tablica opcjonalnych sprite'ów. Nie możesz indeksować opcjonalnej, więc musisz ją rozpakować ... zobacz edytowaną odpowiedź.Najlepsze, co możesz teraz zrobić, to utworzyć tablicę z początkową liczbą powtarzającą się zerem:
Następnie możesz wpisać dowolne wartości.
W Swift 3.0 :
źródło
Odpowiedź na to pytanie została już udzielona, ale dodatkowe informacje w wersji Swift 4:
W przypadku wydajności należy zarezerwować pamięć na tablicę, w przypadku jej dynamicznego tworzenia, np. Dodawania elementów za pomocą
Array.append()
.Jeśli znasz minimalną ilość elementów, które dodasz do niego, ale nie maksymalną, powinieneś raczej użyć
array.reserveCapacity(minimumCapacity: 64)
.źródło
Zadeklaruj pusty SKSpriteNode, aby nie było potrzeby rozpakowywania
źródło
Na razie najbliższa semantycznie byłaby krotka ze stałą liczbą elementów.
Ale jest to (1) bardzo niewygodne w użyciu, a (2) układ pamięci jest niezdefiniowany. (przynajmniej mi nieznane)
źródło
Szybki 4
Możesz w pewnym sensie myśleć o tym jako o tablicy obiektów w porównaniu z tablicą odniesień.
[SKSpriteNode]
musi zawierać rzeczywiste obiekty[SKSpriteNode?]
może zawierać odwołania do obiektów lubnil
Przykłady
Tworzenie tablicy z 64 domyślnymi
SKSpriteNode
:Tworzenie tablicy z 64 pustymi gniazdami (inaczej opcjonalnymi ):
Konwersja tablicy opcji na tablicę obiektów (zwijanie
[SKSpriteNode?]
do[SKSpriteNode]
):Wynik
count
wynikowyflatSprites
zależy od liczby obiektów woptionalSprites
: puste opcje będą ignorowane, czyli pomijane.źródło
flatMap
jest przestarzały, należy go zaktualizować,compactMap
jeśli to możliwe. (Nie mogę edytować tej odpowiedzi)Jeśli chcesz mieć tablicę o stałym rozmiarze i zainicjować ją
nil
wartościami, możesz użyćUnsafeMutableBufferPointer
, przydzielić jej pamięć 64 węzłom, a następnie odczytywać / zapisywać z / do pamięci przez indeksowanie instancji typu wskaźnika. Ma to również tę zaletę, że pozwala uniknąć sprawdzania, czy pamięć musi zostać ponownie przydzielonaArray
. Byłbym jednak zaskoczony, gdyby kompilator nie zoptymalizował tego dla tablic, które nie mają więcej wywołań metod, które mogą wymagać zmiany rozmiaru, poza miejscem tworzenia.Nie jest to jednak zbyt przyjazne dla użytkownika. Zróbmy więc opakowanie!
To jest klasa, a nie struktura, więc istnieje tutaj pewien koszt zliczania odniesień. Zamiast tego możesz zmienić to na
struct
a, ale ponieważ Swift nie zapewnia możliwości używania inicjatorów kopiowania ideinit
struktur, będziesz potrzebować metody deallocation (func release() { memory.deallocate() }
), a wszystkie skopiowane wystąpienia struktury będą odwoływać się do tej samej pamięci.Teraz ta klasa może być wystarczająco dobra. Jego użycie jest proste:
Aby uzyskać więcej protokołów do zaimplementowania zgodności, zobacz dokumentację tablicy (przewiń do sekcji Relacje ).
źródło
Jedną z rzeczy, które możesz zrobić, byłoby utworzenie słownika. Może być trochę niechlujny, biorąc pod uwagę, że szukasz 64 elementów, ale spełnia swoje zadanie. Nie jestem pewien, czy jest to „preferowany sposób”, ale zadziałał przy użyciu tablicy struktur.
źródło
tasks[65] = foo
zarówno w tym przypadku, jak iw przypadku tablicy z pytania.