Как преобразовать Int в NSData в Swift?

В Objective-C я использую следующий код для

  • Преобразуйте переменную Int в NSData, пакет байтов.

    int myScore = 0;
    NSData *packet = [NSData dataWithBytes:&myScore length:sizeof(myScore)];
    
  • Используйте преобразованную переменную NSData в метод.

    [match sendDataToAllPlayers: 
    packet withDataMode: GKMatchSendDataUnreliable 
    error: &error];
    

Я попытался преобразовать код Objective-C в Swift:

var myScore : Int = 0

func sendDataToAllPlayers(packet: Int!,
            withDataMode mode: GKMatchSendDataMode,
            error: NSErrorPointer) -> Bool {

            return true
}

Однако я не могу преобразовать переменную Int в NSData и использовать ее как метод. Как я могу это сделать?

Ответ 1

С Swift 3.x до 5.0:

var myInt = 77
var myIntData = Data(bytes: &myInt, 
                     count: MemoryLayout.size(ofValue: myInt))

Ответ 2

В современных версиях Swift я бы сделал:

let score = 1000
let data = withUnsafeBytes(of: score) { Data($0) }
e8 03 00 00 00 00 00 00 

И преобразовать это Data обратно в Int:

let value = data.withUnsafeBytes {
    $0.bindMemory(to: Int.self)[0]
}

Обратите внимание, что при работе с двоичными представлениями чисел, особенно при обмене с каким-либо удаленным сервисом/устройством, вы можете захотеть сделать порядковый номер явным, например,

let data = withUnsafeBytes(of: score.littleEndian) { Data($0) }
 e8 03 00 00 00 00 00 00 

И преобразовать это Data обратно в Int:

let value = data.withUnsafeBytes {
    $0.bindMemory(to: Int.self)[0].littleEndian
}

В отличие от формата с прямым порядком байтов, также известного как "сетевой порядок байтов":

let data = withUnsafeBytes(of: score.bigEndian) { Data($0) }
 00 00 00 00 00 00 03 e8

И преобразовать это Data обратно в Int:

let value = data.withUnsafeBytes {
    $0.bindMemory(to: Int.self)[0].bigEndian
}

Разумеется, если вы не хотите беспокоиться о порядке байтов, вы можете использовать какой-то установленный стандарт, такой как JSON (или даже XML).


Для воспроизведения Swift 2 см. предыдущую редакцию этого ответа.

Ответ 3

Вы можете преобразовать следующим образом:

var myScore: NSInteger = 0
let data = NSData(bytes: &myScore, length: sizeof(NSInteger))