2017-06-04 2 views
0

Je veux convertir UInt16 au tableau UInt8, mais je reçois le message d'erreur suivant:Comment convertir UInt16 en UInt8 en Swift 3?

« init » est disponible: utilisation withMemoryRebound (pour: Capacité: _) 'à afficher temporairement la mémoire comme une autre mise en page -compatible type.

Le code:

let statusByte: UInt8 = UInt8(status) 
    let lenghtByte: UInt16 = UInt16(passwordBytes.count) 

    var bigEndian = lenghtByte.bigEndian 

    let bytePtr = withUnsafePointer(to: &bigEndian) { 
     UnsafeBufferPointer<UInt8>(start: UnsafePointer($0), count: MemoryLayout.size(ofValue: bigEndian)) 
    } 

Répondre

3

Comme le message d'erreur indique, vous devez utiliser withMemoryRebound() pour réinterpréter le pointeur sur UInt16 comme un pointeur vers UInt8:

let bytes = withUnsafePointer(to: &bigEndian) { 
    $0.withMemoryRebound(to: UInt8.self, capacity: MemoryLayout.size(ofValue: bigEndian)) { 
     Array(UnsafeBufferPointer(start: $0, count: MemoryLayout.size(ofValue: bigEndian))) 
    } 
} 

Les fermetures sont invoquées avec des pointeurs ($0) qui ne sont valide pour la durée de vie de la fermeture et ne doit pas être passé à l'extérieur pour une utilisation ultérieure. C'est pourquoi un Array est créé et utilisé comme valeur de retour.

Il y a une solution plus simple cependant:

let bytes = withUnsafeBytes(of: &bigEndian) { Array($0) } 

Explication:withUnsafeBytes invoque la fermeture avec un UnsafeRawBufferPointer au stockage de la variable bigEndian. Depuis UnsafeRawBufferPointer est un Sequence de UInt8, un tableau peut être créé à partir de cela avec Array($0).

3

Vous pouvez étendre le protocole entier et de créer une propriété de données comme suit:

extension Integer { 
    var data: Data { 
     var source = self 
     return Data(bytes: &source, count: MemoryLayout<Self>.size) 
    } 
} 

Swift 3 données est conforme à MutableCollection de sorte que vous pouvez simplement créer un tableau d'octets de vos données UInt16:

extension Data { 
    var array: [UInt8] { return Array(self) } 
} 

let lenghtByte = UInt16(8) 
let bytePtr = lenghtByte.bigEndian.data.array // [0, 8]