2015-01-30 11 views
9

Also habe ich herausgefunden, wie NSData in swift zu extrahieren, aber ich bin immer mit Bezug zu verwechseln Einstellung es:mit NSData Arbeiten in schnellen

var testBytes : [Byte] = [0x14, 0x00, 0xAB, 0x45, 0x49, 0x1F, 0xEF, 0x15,  
          0xA8, 0x89, 0x78, 0x0F, 0x09, 0xA9, 0x07, 0xB0, 
          0x01, 0x20, 0x01, 0x4E, 0x38, 0x32, 0x35, 0x56, 
          0x20, 0x20, 0x20, 0x00] 

var msgData = NSData(bytes: testBytes, length: testBytes.count) 

println("\(msgData)") 


var length : Int = testBytes.count 

var out: NSInteger = 0 

let ptr = UnsafePointer<UInt8>(msgData.bytes) 
var bytes = UnsafeBufferPointer<UInt8>(start: ptr, count: 28) 

So kann ich, wenn ich ein bestimmtes Byte zugreifen möchten bekommen es mit so etwas wie:

let targetAddress = UInt32(bytes[2]) << 16 | 
    UInt32(bytes[3]) << 8 | 
    UInt32(bytes[4]) << 0 

Nun sage ich Wert mit so etwas wie setzen wollten:

bytes[11] = UInt8(UInt32(bytes[11]) | 0x0FF) 

ich einen Fehler von 012 erhalten. Ich habe auch versucht, &bytes[11] zu verwenden, die auch nicht zu fliegen scheint.

Ich nehme an, dies liegt daran, dass das Array einen unsicheren Pufferzeiger verwendet. Gibt es einen einfachen Anruf, über den ich einige beschönige, damit die Aufgabe richtig funktioniert?

Antwort

14

Wenn Sie die Bytes aus dem NSData Objekt abgerufen ändern möchten, dann sollten Sie kopieren die Bytes in einem separaten Array

var bytes = [UInt8](count: msgData.length, repeatedValue: 0) 
msgData.getBytes(&bytes, length: bytes.count) 

bytes[11] = UInt8(UInt32(bytes[11]) | 0x0FF) 

NSData ein unveränderliches Objekt ist, und

let ptr = UnsafePointer<UInt8>(msgData.bytes) 

ist ein konstanter Zeiger, daher dürfen Sie die angezeigten Daten nicht ändern.

Alternativ können Sie ein wandelbar Datenobjekt von Anfang an:

var msgData = NSMutableData(bytes: testBytes, length: testBytes.count) 

let ptr = UnsafeMutablePointer<UInt8>(msgData.mutableBytes) 
var bytes = UnsafeMutableBufferPointer<UInt8>(start: ptr, count: msgData.length) 

bytes[11] = UInt8(UInt32(bytes[11]) | 0x0FF) 

Beachten Sie die Verwendung von msgData.mutableBytes statt msgData.bytes. Dadurch werden die Daten in msgData direkt geändert.