我之前在Swift 4.2中使用此代码生成一个id:
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
在Swift 5.0上弃用。我怎么解决这个问题?
在Swift 5中,withUnsafeBytes()
的Data
方法用(无类型的)UnsafeRawBufferPointer
调用闭包,你可以从原始记忆中获取load()
值:
let value = data.withUnsafeBytes { $0.load(as: UInt32.self) }
(比较Swift论坛中的How to use Data.withUnsafeBytes in a well-defined manner?)。请注意,这要求内存在4字节边界上对齐。有关替代方案,请参阅round trip Swift number types to/from Data。
另请注意,从Swift 4.2开始,您可以使用新的Random
API创建一个随机的32位整数:
let randomId = UInt32.random(in: .min ... .max)
在Xcode 10.2上,使用$0.load(as:)
的Swift 5在从指针读取或写入时都不适用于我。
相反,使用$0.baseAddress?.assumingMemoryBound(to:)
似乎运作良好。
从指针缓冲区读取示例(代码与问题无关):
var reachability: SCNetworkReachability?
data.withUnsafeBytes { ptr in
guard let bytes = ptr.baseAddress?.assumingMemoryBound(to: Int8.self) else {
return
}
reachability = SCNetworkReachabilityCreateWithName(nil, bytes)
}
写入缓冲区指针的示例(代码与问题无关):
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
}
}
问题的代码如下:
let value = data.withUnsafeBytes {
$0.baseAddress?.assumingMemoryBound(to: UInt32.self)
}
在'withUnsafeBytes' is deprecated: use withUnsafeBytes<R>(…)
警告持续存在的情况下,它看起来像the compiler can get confused when the closure has only one line。使闭包有两行或更多行可能会消除歧义。