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.