Konvertieren NSData an Integer in Swift
In Objective-C code sah diese und funktionierte einwandfrei,
NSInteger random = arc4random_uniform(99) + 1
NSData *data = [NSData dataWithBytes:& random length: sizeof(random)];
int value = *(int*)([data bytes]);
Wie kann man das in Swift?
Du musst angemeldet sein, um einen Kommentar abzugeben.
Wie diese:
sizeofValue(random)
sizeofValue
istMemoryLayout.size(ofValue: value)
Im Swift 4:
Gibt es ein paar Dinge zu beachten, wenn man ein integer-Wert aus einer
Data
stream. Fehler und endian Typ. So kam ich mit einer Funktion in eine extension zuData
folgert, dass Fehler vom Typ integer, die Sie extrahieren möchten, und übergibt endian Typ undIndex
als Parameter. Die Typen der ganzen zahlen, die extrahiert werden können, sind alle, die sich konform zuFixedWidthInteger
Protokoll.Erinnerung: Diese Funktion nicht überprüfen, ob die
Index
Bereich ist innerhalb der Grenzen desData
Puffer auf, so dass es Abstürzen kann, abhängig von der Größe des Typs, die extrahiert wird, in Bezug auf das Ende des Puffers.Beispiel:
Ergebnisse:
number1 is 8191
number2 is 65311
number3 is -225
number4 is 8191
Beachten Sie die Funktion Aufrufe um zu sehen, wie der Typ, der extrahiert werden, ist zufällig. Natürlich endian Typ macht keinen Sinn für
Int8
oderUInt8
, aber die Funktion arbeitet wie erwartet.Werte kann später umgewandelt werden, um
Int
wenn nötig.UInt8
ist einfach zu benutzen, eine Tiefstellung wenn Sie genau wissen, der index der byte, die Sie wollen:data[index]
Data.Index
innerhalb einerData
Erweiterung überflüssig ist. Verwenden Sie nurIndex
MemoryLayout
.stride
- nichtsize
. Siehe die Dokumentation fürstride
, die es definieren als "Die Anzahl der bytes vom Anfang einer Instanz von T, um den Anfang des nächsten, wenn gespeichert in zusammenhängenden Speicher oder in einem Array<T>" und "die Anzahl der bytes verschoben werden, wenn ein UnsafePointer<T> Instanz ist erhöht"Für Swift 3, können Sie dies tun (little-endian, aber ähnlich groß):
Können Sie ändern, ergänzen generics, etc. passen andere primitive Typen (und variieren je nach den endian der Daten-bytes).
Finden Sie vielleicht diese Methode ist nützlich, wenn Sie es tun, eine Menge:
Die Funktion nimmt als parameter den start-position in den Daten zu Lesen, die einen numerischen Typ, und es gibt einen Wert zurück, der eine Art abgeleitet werden, was Sie sind zuweisen.
Beispiel:
liest eine 4-byte-Ganzzahl von position 10 in den Daten.
Wenn Sie ändern
UInt32
zuUInt16
es liest zwei bytes.Daten zu interger danke @rghome
Mein Beitrag mit einer raschen 3.1 Erweiterung :
Einfach anrufen .int, um Ihren Wert, genau wie dieser :
Erweitern zu können, Daten-Protokoll, erstellen Sie eine Allgemeine metho, Rückkehr der bytes von Speicher Daten-Speicher und wandeln Sie Sie oder setzen Sie den resultierenden Typ ausdrücklich als gebraucht:
Tests mit
Int
Tests mit
UInt32
Tests mit Doppel -
Wenn Sie möchten, zu extrahieren, eine subdata einfach Tiefgestellt Ihre Daten: