Ich will meinen Swift passieren Array
account.chats
zu chatsViewController.chats
durch Verweis (so , dass , wenn ich einen Chat hinzufügen account.chats
, chatsViewController.chats
noch Punkte account.chats
). Das heißt, ich möchte nicht, dass Swift die beiden Arrays trennt, wenn sich die Länge account.chats
ändert.
arrays
swift
pass-by-reference
ma11hew28
quelle
quelle
account
eine globale Variable erstellt und diechats
Eigenschaft von definiertChatsViewController
als :var chats: [Chat] { return account.chats }
.Antworten:
Strukturen in Swift werden als Wert übergeben, aber Sie können den
inout
Modifikator verwenden, um Ihr Array zu ändern (siehe Antworten unten). Klassen werden als Referenz übergeben.Array
undDictionary
in Swift sind als Strukturen implementiert.quelle
NSArray
weilNSArray
und Swift-Array subtile semantische Unterschiede aufweisen (z. B. Referenztyp), und dies führt möglicherweise zu weiteren Fehlern.inout
mit Structs?Für den Funktionsparameteroperator verwenden wir:
let (es ist der Standardoperator, sodass wir let weglassen können ), um einen Parameter konstant zu machen (dies bedeutet, dass wir nicht einmal die lokale Kopie ändern können);
var , um es variabel zu machen (wir können es lokal ändern, aber es hat keinen Einfluss auf die externe Variable, die an die Funktion übergeben wurde); und
inout , um es zu einem In-Out-Parameter zu machen. In-out bedeutet in der Tat, Variablen als Referenz und nicht als Wert zu übergeben. Und es erfordert nicht nur, Wert als Referenz zu akzeptieren, sondern ihn auch als Referenz zu übergeben, also übergeben Sie ihn mit & -
foo(&myVar)
anstatt nurfoo(myVar)
Also mach es so:
Um genau zu sein, handelt es sich nicht nur um eine Referenz, sondern um einen echten Alias für die externe Variable. Sie können also einen solchen Trick mit jedem Variablentyp ausführen, z. B. mit einer Ganzzahl (Sie können ihr einen neuen Wert zuweisen), obwohl dies möglicherweise kein Wert ist Gute Praxis und es kann verwirrend sein, die primitiven Datentypen wie folgt zu ändern.
quelle
inout
Position geändert, dhfunc addItem(localArr: inout [Int])
var
auch für das Funktionsparameterattribut nicht mehr verfügbar.Definieren Sie sich eine
BoxedArray<T>
, die dieArray
Schnittstelle implementiert , aber alle Funktionen an eine gespeicherte Eigenschaft delegiert. So wieVerwenden Sie das
BoxedArray
überall dort, wo Sie ein verwenden möchtenArray
. Das Zuweisen einesBoxedArray
Willens erfolgt durch Referenz, es ist eine Klasse, und daher sind Änderungen an der gespeicherten Eigenschaft über dieArray
Schnittstelle für alle Referenzen sichtbar.quelle
String
ein Subtyp vonAny
ABER ist, wenn Sieimport Foundation
dannString
ein Subtyp von werdenAnyObject
.Verwenden Sie für die Swift-Versionen 3-4 (XCode 8-9)
quelle
Etwas wie
???
quelle
func test(b: inout [Int])
... vielleicht ist dies eine alte Syntax; Ich bin erst 2016 zu Swift gekommen und diese Antwort stammt aus dem Jahr 2014. Vielleicht waren die Dinge früher anders?Eine andere Möglichkeit besteht darin, dass der Verbraucher des Arrays den Eigentümer nach Bedarf danach fragt. Zum Beispiel etwas in der Art von:
Sie können das Array dann innerhalb der Account-Klasse beliebig ändern. Beachten Sie, dass dies nicht hilfreich ist, wenn Sie das Array auch in der View Controller-Klasse ändern möchten.
quelle
Die Verwendung
inout
ist eine Lösung, die sich für mich jedoch nicht sehr schnell anfühlt, da Arrays Werttypen sind. Stilistisch bevorzuge ich persönlich die Rückgabe einer mutierten Kopie:quelle
inout
allgemein besser ist, weil es Batterie spart. Ich würde sagen, dass die Lesbarkeit, Unveränderlichkeit und Thread-Sicherheit dieser Lösung allgemein besser ist und dass inout nur in den seltenen Fällen als Optimierung verwendet werden sollte, in denen der Anwendungsfall dies rechtfertigt.Verwenden Sie a
NSMutableArray
oder aNSArray
, die Klassen sindAuf diese Weise müssen Sie keinen Wraper implementieren und können den Build als Bridging verwenden
quelle