Chcę przekazać moje Swift Array
account.chats
na chatsViewController.chats
odnośnik (tak, że kiedy dodać czat account.chats
, chatsViewController.chats
nadal wskazuje account.chats
). To znaczy, nie chcę, aby Swift rozdzielał dwie tablice, gdy account.chats
zmienia się długość .
arrays
swift
pass-by-reference
ma11hew28
źródło
źródło
account
zmienną globalną i określaniuchats
właściwościChatsViewController
jak:var chats: [Chat] { return account.chats }
.Odpowiedzi:
Struktury w Swift są przekazywane według wartości, ale możesz użyć
inout
modyfikatora, aby zmodyfikować swoją tablicę (patrz odpowiedzi poniżej). Klasy są przekazywane przez referencje.Array
awDictionary
Swift są implementowane jako struktury.źródło
NSArray
ponieważNSArray
tablica Swift ma subtelne różnice semantyczne (takie jak typ referencyjny), co może prowadzić do większej liczby błędów.inout
ze Structs?Dla operatora parametru funkcji używamy:
let (jest to domyślny operator, więc możemy pominąć let ), aby uczynić parametr stałym (oznacza to, że nie możemy modyfikować nawet lokalnej kopii);
var, aby uczynić go zmiennym (możemy go modyfikować lokalnie, ale nie wpłynie to na zmienną zewnętrzną, która została przekazana do funkcji); i
inout, aby był to parametr in-out. In-out oznacza w rzeczywistości przekazywanie zmiennej przez odniesienie, a nie przez wartość. Wymaga nie tylko akceptowania wartości przez odniesienie, ale także przekazywania jej przez referencję, więc przekazuj ją za pomocą & -
foo(&myVar)
zamiast po prostufoo(myVar)
Więc zrób to tak:
Dokładnie to nie jest tylko odniesienie, ale prawdziwy alias dla zmiennej zewnętrznej, więc możesz zrobić taką sztuczkę z dowolnym typem zmiennej, na przykład z liczbą całkowitą (możesz przypisać jej nową wartość), chociaż może to nie być dobrą praktyką i modyfikowanie takich pierwotnych typów danych może być mylące.
źródło
inout
pozycja uległa zmianie, czylifunc addItem(localArr: inout [Int])
var
nie jest już dostępny dla atrybutu parametru funkcji.Zdefiniuj siebie a,
BoxedArray<T>
który implementujeArray
interfejs, ale deleguje wszystkie funkcje do przechowywanej właściwości. Takie jakUżyj
BoxedArray
dowolnego miejsca, w którym chcesz użyćArray
. PrzypisanieBoxedArray
woli będzie przez odniesienie, jest to klasa, a tym samym zmiany w przechowywanej właściwości, poprzezArray
interfejs, będą widoczne dla wszystkich referencji.źródło
String
jest podtypemAny
ALE, jeśliimport Foundation
następnieString
stajesz się podtypemAnyObject
.W przypadku wersji Swift 3-4 (XCode 8-9) użyj
źródło
Coś jak
???
źródło
func test(b: inout [Int])
... może to stara składnia; Swift dostałem dopiero w 2016 roku, a ta odpowiedź pochodzi z 2014 roku, więc może kiedyś było inaczej?Inną opcją jest poproszenie konsumenta macierzy o to w razie potrzeby. Na przykład coś w rodzaju:
Następnie możesz dowolnie modyfikować tablicę w klasie Account. Zauważ, że to nie pomaga, jeśli chcesz również zmodyfikować tablicę z klasy kontrolera widoku.
źródło
Używanie
inout
jest jednym z rozwiązań, ale nie wydaje mi się zbyt szybkie, ponieważ tablice są typami wartości. Stylistycznie osobiście wolę zwrócić zmutowaną kopię:źródło
inout
jest to uniwersalnie lepsze, ponieważ oszczędza baterię. Powiedziałbym, że czytelność, niezmienność i bezpieczeństwo wątków tego rozwiązania są ogólnie lepsze i że inout powinien być używany tylko jako optymalizacja w tych rzadkich przypadkach, gdy uzasadnia to przypadek użycia.użyj a
NSMutableArray
lub aNSArray
, które są klasamiw ten sposób nie musisz implementować żadnego opakowania i możesz użyć budowania w mostkowaniu
źródło