swift deprecated unsafe-pointers

Swift 5.0: ''withUnsafeBytes'' está en desuso: use `withUnsafeBytes<R>(...)



deprecated unsafe-pointers (2)

En Swift 5, el método withUnsafeBytes() de Data llama al cierre con un UnsafeRawBufferPointer (sin tipo), y puede load() el valor de la memoria sin formato:

let value = data.withUnsafeBytes { $0.load(as: UInt32.self) }

( ¿Cómo usar Data.withUnsafeBytes de una manera bien definida? en el foro de Swift). Tenga en cuenta que esto requiere que la memoria esté alineada en un límite de 4 bytes. Para alternativas consulte los tipos de números Swift de ida y vuelta a / desde Datos .

Tenga en cuenta también que a partir de Swift 4.2 puede crear un entero aleatorio de 32 bits simplemente utilizando la nueva API Random :

let randomId = UInt32.random(in: .min ... .max)

Anteriormente utilicé este código en Swift 4.2 para generar una identificación:

public static func generateId() throws -> UInt32 { let data: Data = try random(bytes: 4) let value: UInt32 = data.withUnsafeBytes { $0.pointee } // deprecated warning! return value // + some other stuff }

withUnsafeBytes está en desuso en Swift 5.0. ¿Como puedo resolver esto?


En Xcode 10.2, Swift 5, usar $0.load(as:) no me funcionó, tanto al leer desde el puntero como al escribir en él.

En su lugar, el uso de $0.baseAddress?.assumingMemoryBound(to:) parece funcionar bien.

Ejemplo de lectura del búfer de puntero (el código no está relacionado con la pregunta):

var reachability: SCNetworkReachability? data.withUnsafeBytes { ptr in guard let bytes = ptr.baseAddress?.assumingMemoryBound(to: Int8.self) else { return } reachability = SCNetworkReachabilityCreateWithName(nil, bytes) }

Ejemplo de escritura en el puntero del búfer (el código no está relacionado con la pregunta):

try outputData.withUnsafeMutableBytes { (outputBytes: UnsafeMutableRawBufferPointer) in let status = CCKeyDerivationPBKDF(CCPBKDFAlgorithm(kCCPBKDF2), passphrase, passphrase.utf8.count, salt, salt.utf8.count, CCPseudoRandomAlgorithm(kCCPRFHmacAlgSHA1), rounds, outputBytes.baseAddress?.assumingMemoryBound(to: UInt8.self), kCCKeySizeAES256) guard status == kCCSuccess else { throw Error.keyDerivationError } }

El código de la pregunta se vería así:

let value = data.withUnsafeBytes { $0.baseAddress?.assumingMemoryBound(to: UInt32.self) }

En los casos en que la ''withUnsafeBytes'' is deprecated: use withUnsafeBytes<R>(…) advertencia persiste, parece que el compilador puede confundirse cuando el cierre solo tiene una línea . Hacer que el cierre tenga dos o más líneas podría eliminar la ambigüedad.