Swift - welche Typen sollen verwendet werden? NSString oder String

109

Mit der Einführung von Swift habe ich versucht, mich mit der neuen Sprache vertraut zu machen

Ich bin ein iOS-Entwickler und würde Typen wie NSString, NSInteger, NSDictionaryin einer Anwendung verwenden. Ich habe festgestellt, dass im E-Book "The Swift Programming Language" von Apple die Swift-Typen verwendet werdenString, Int, Dictionary

Ich habe festgestellt, dass die Swift-Typen einige der Funktionen der Foundation-Typen nicht haben (oder anders benannt sind). Hat zum Beispiel NSStringeine lengthEigenschaft. Aber ich konnte keinen ähnlichen für den Swift finden String.

Ich frage mich, ob ich für eine iOS-Anwendung weiterhin die Foundation-Typen verwenden soll.

Alec
quelle
3
Lieber String. Die StringFunktionalität ist in der Alpha-Version jedoch noch etwas eingeschränkt und wird daher NSStringvorerst stärker genutzt. Wir hoffen, dass sie die API bis GA reparieren.
Sulthan
1
Sie können auch anrufen countElements(str), um diesen bestimmten Teil Ihrer Frage zu beantworten.
Nate Cook
Besser, Sie können "foo".length" directly in Swift. An implicit cast to NSString aufrufen` wird vom Compiler für Sie hinzugefügt!
Gabriele Petronella
1
@GabrielePetronella .length funktioniert bei Sonderzeichen möglicherweise nicht richtig. Zum Beispiel Emoji oder chinesische Schriftzeichen, die 2 oder 3 Unicode-Zeichen aufnehmen. countElements ist die richtige Methode.
Fogmeister

Antworten:

98

Sie sollten nach Möglichkeit die nativen Swift-Typen verwenden. Die Sprache ist für ihre Verwendung optimiert, und die meisten Funktionen werden zwischen den nativen Typen und den FoundationTypen überbrückt .

Während Stringund NSStringmeistens austauschbar sind, dh Sie können StringVariablen an Methoden übergeben, die NSStringParameter annehmen und umgekehrt, scheinen einige Methoden ab diesem Moment nicht automatisch überbrückt zu werden. In dieser Antwort finden Sie eine Diskussion zum Abrufen der Länge eines Strings. In dieser Antwort finden Sie eine Diskussion containsString()zum Überprüfen auf Teilzeichenfolgen. (Haftungsausschluss: Ich bin der Autor für beide Antworten)

Ich habe andere Datentypen nicht vollständig untersucht, aber ich gehe davon aus, dass eine Version der oben genannten auch für Array/ NSArray, Dictionary/ NSDictionaryund die verschiedenen Nummerntypen in Swift und giltNSNumber

Wenn Sie einen der Foundation-Typen verwenden müssen, können Sie diese entweder verwenden, um Variablen / Konstanten explizit einzugeben, wie in var str: NSString = "An NSString"oder bridgeToObjectiveC()für eine vorhandene Variable / Konstante eines Swift-Typs, wie in str.bridgeToObjectiveC().length. Sie können a auch in a umwandeln String, NSStringindem Sie verwenden str as NSString.

Die Notwendigkeit, dass diese Techniken die Foundation-Typen oder zumindest einige von ihnen explizit verwenden, kann jedoch in Zukunft überholt sein, da beispielsweise die String/ NSStringbridge nach den Angaben in der Sprachreferenz vollständig nahtlos sein sollte.

Eine ausführliche Diskussion zu diesem Thema finden Sie unter Verwenden von Swift mit Kakao und Objective-C: Arbeiten mit Kakaodatentypen

Cezar
quelle
4
+1 für den Verweis auf bridgeToObjectiveC()und die Erläuterung der Verbindung zwischen NSString und Swift's String.
Chris
2
Hey Cezar, ich denke, bridgeToObjectiveC ist veraltet, wenn Sie Ihre Antwort aktualisieren möchten.
Dan Beaulieu
Ich stelle im Swift 3-Handbuch fest, dass die Foundation-Typen als Referenz übergeben werden, während die nativen Typen als Wert übergeben werden (oder so etwas, das ich derzeit nicht vollständig verstehe). Es wäre großartig, wenn Sie Ihre Antwort über die Auswirkungen aktualisieren könnten.
Nigel B. Peck
27

NSString: Erstellt Objekte, die sich im Heap befinden und immer als Referenz übergeben werden.

String: Es ist ein Werttyp, wenn wir ihn übergeben, er wird als Wert übergeben. String wie Struct und Enum selbst ein Struct in Swift.

public struct String {
 // string implementation 
}

Eine Kopie wird jedoch nicht erstellt, wenn Sie bestanden haben. Es erstellt eine Kopie, wenn Sie es zum ersten Mal mutieren.

Die Zeichenfolge wird automatisch als NSString an Objective-C überbrückt. Wenn die Swift Standard Library nicht vorhanden ist, müssen Sie das Foundation-Framework importieren, um Zugriff auf von NSString definierte Methoden zu erhalten.

Swift String ist sehr leistungsfähig und verfügt über eine Vielzahl integrierter Funktionen.

Initialisierung auf String:

var emptyString = ""             // Empty (Mutable)
let anotherString = String()     // empty String immutable    
let a = String(false)           // from boolean: "false"
let d = String(5.999)           //  "    Double "5.99"
let e = String(555)             //  "     Int "555"
// New in Swift 4.2 
let hexString = String(278, radix: 18, uppercase: true) // "F8"

Erstellen Sie einen String aus sich wiederholenden Werten:

 let repeatingString = String(repeating:"123", count:2) // "123123"

In Swift 4 -> Strings sind Zeichensammlung:

Jetzt kann String alle Operationen ausführen, die jeder für den Sammlungstyp ausführen kann.

Weitere Informationen finden Sie in den Apple-Dokumenten.

Sandy Rawat
quelle
2
Diese Antwort sollte mehr Stimmen bekommen. Dies ist der grundlegende Unterschied zwischen String und NSString. Überall sonst sind sie fast austauschbar
Max
Gute Antwort. value vs ref type note besonders.
spnkr
11

Am besten verwenden Sie native Swift-Typen und -Klassen, da einige andere festgestellt haben, dass NSString eine gebührenfreie Übersetzung in String bietet. Sie sind jedoch nicht zu 100% gleich, z. B. die folgenden

var nsstring: NSString = "\U0001F496"
var string: String = "\U0001F496"

nsstring.length
count(string)

Sie müssen die Methode count () verwenden, um die Zeichen in der Zeichenfolge zu zählen. Beachten Sie außerdem, dass nsstring.length 2 zurückgibt, da die Länge basierend auf UTF16 gezählt wird.

Ähnlich, JA Das gleiche, NEIN

Emanuel
quelle
7

Stringund NSStringsind austauschbar, so dass es nicht wirklich wichtig ist, welche Sie verwenden. Sie können immer zwischen den beiden mit verwenden

let s = "hello" as NSString

oder auch

let s: NSString  = "hello"

NSIntegerist nur ein Alias ​​für ein intoder ein long(abhängig von der Architektur), also würde ich nur verwenden Int.

NSDictionaryist eine andere Sache, da Dictionaryes sich um eine völlig separate Implementierung handelt.

Im Allgemeinen würde ich mich nach Möglichkeit an schnelle Typen halten, und Sie können bei Bedarf jederzeit zwischen den beiden konvertieren, indem Sie die bridgeToObjectiveC()von schnellen Klassen bereitgestellte Methode verwenden.

Gabriele Petronella
quelle
Der IntDatentyp von Swift wird im Buch als mit der Wortgröße der Architektur identisch angegeben. NSIntegerist auch die gleiche Größe wie die Wortgröße der Architektur.
MaddTheSane
6

Da die Ziel-C-Typen immer noch dynamisch versendet werden, werden sie wahrscheinlich langsamer sein. Ich würde sagen, dass Sie am besten mit den nativen Swift-Typen bedient werden, es sei denn, Sie müssen mit Objective-C-APIs interagieren

Jiaaro
quelle
Ja das ist genau die Antwort. Und die Vermeidung von dynamisch ausgelösten Methoden und des Zugriffs auf Objektvariablen ist alles, was diese Geschwindigkeitsverbesserungen ausmacht, über die sie auf der WWDC gesprochen haben. In der Vergangenheit verwendeten alle, die sich Sorgen um die Leistung machten, C ++ - Zeichenfolgen und Container, um statisches Dispatching zu erhalten.
Lothar
5

Verwenden Sie die nativen Swift-Typen, wann immer Sie können. Im Fall von String haben Sie jedoch "nahtlosen" Zugriff auf alle NSStringMethoden wie folgt:

var greeting = "Hello!"
var len = (greeting as NSString).length
Nate Cook
quelle
4

Swift 4 Update

String erhält Revisionen in Swift 4. Jetzt können Sie count direkt darauf aufrufen und es betrachtet Graphemcluster als 1 Stück, wie ein Emoji. NSString wird nicht aktualisiert und zählt es auf andere Weise.

var nsstring: NSString = "👩‍👩‍👧‍👦"
var string: String = "👩‍👩‍👧‍👦"

print(nsstring.length) // 11
print(string.count)    // 1
Fangming
quelle
1
NSStrings wird wahrscheinlich nicht aktualisiert, um mit Graphemclustern fertig zu werden: Es würde zu viele Apps beschädigen, die auf dem alten Verhalten beruhen. Außerdem NSString.lengthzählt die UTF16 Zeichen.
MaddTheSane
0

String ist eine Struktur

// im Swift-Modul

public struct String

{

}}

NSString ist eine Klasse

// im Foundation-Modul

offene Klasse NSString: NSObject

{

}}

kashish makkar
quelle