Data withUnsafeBytes 已弃用
Data withUnsafeBytes is deprecated
我从我正在开发的应用程序中获得了这段代码。当 BLE 人离开团队时,我继承了这段代码。我不擅长低层次的东西和数据的东西。我是 UI/UX 前端人员,现在我确实需要亲自动手。这段代码现在有点旧并且使用了不推荐使用的代码。我一直试图让警告静音,但没有成功,但我总是以相同的代码或错误结束。
这是生成警告的代码。使用 withUnsafeBytes
时在 return 行
extension Data {
func scanValueFromData<T>(start: Int = 0, invalid: T) -> (T, Int) {
let length = MemoryLayout<T>.size
guard self.count >= start + length else {
return (invalid, start+length)
}
return (self.subdata(in: start..<start+length).withUnsafeBytes{ [=10=].pointee }, start+length)
}
}
此方法用于将字节数组解码为结构。我从 BLE 服务获取数据,各种变量被打包到一个字节数组中。
如果有任何解决此问题的方法或更好的方法来做 id。
此处弃用的 withUnsafeBytes
版本是将底层指针绑定到已知类型 (Data.withUnsafeBytes<R, T>(_ body: (UnsafePointer<T>) throws -> R) rethrows -> R
) 的版本。
首选的替换版本是不以这种方式绑定的版本,returns 原始缓冲区指针 (withUnsafeBytes<R>(_ body: (UnsafeRawBufferPointer) throws -> R) rethrows -> R
);幸运的是,在这些之间转换只会改变你从指针读取的方式:
extension Data {
func scanValueFromData<T>(start: Int = 0, invalid: T) -> (T, Int) {
let length = MemoryLayout<T>.size
guard self.count >= start + length else {
return (invalid, start + length)
}
return (self.subdata(in: start ..< start + length).withUnsafeBytes { [=10=].load(as: T.self) }, start + length)
}
}
使用 UnsafeRawBufferPointer.load(as:)
您可以安全地从缓冲区中读取一个普通类型 T
。 (请注意,对于非平凡类型调用此方法不安全,但该方法的原始版本也是如此。)
如果想进一步简化,可以避免重复start + length
:
func scanValueFromData<T>(start: Int = 0, invalid: T) -> (T, Int) {
let length = MemoryLayout<T>.size
var value = invalid
if count >= start + length {
value = subdata(in: start ..< start + length).withUnsafeBytes { [=11=].load(as: T.self) }
}
return (value, start + length)
}
甚至更短,以可读性为代价:
func scanValueFromData<T>(start: Int = 0, invalid: T) -> (T, Int) {
let length = MemoryLayout<T>.size
let value = count >= start + length ? subdata(in: start ..< start + length).withUnsafeBytes { [=12=].load(as: T.self) } : invalid
return (value, start + length)
}
我从我正在开发的应用程序中获得了这段代码。当 BLE 人离开团队时,我继承了这段代码。我不擅长低层次的东西和数据的东西。我是 UI/UX 前端人员,现在我确实需要亲自动手。这段代码现在有点旧并且使用了不推荐使用的代码。我一直试图让警告静音,但没有成功,但我总是以相同的代码或错误结束。
这是生成警告的代码。使用 withUnsafeBytes
时在 return 行extension Data {
func scanValueFromData<T>(start: Int = 0, invalid: T) -> (T, Int) {
let length = MemoryLayout<T>.size
guard self.count >= start + length else {
return (invalid, start+length)
}
return (self.subdata(in: start..<start+length).withUnsafeBytes{ [=10=].pointee }, start+length)
}
}
此方法用于将字节数组解码为结构。我从 BLE 服务获取数据,各种变量被打包到一个字节数组中。
如果有任何解决此问题的方法或更好的方法来做 id。
此处弃用的 withUnsafeBytes
版本是将底层指针绑定到已知类型 (Data.withUnsafeBytes<R, T>(_ body: (UnsafePointer<T>) throws -> R) rethrows -> R
) 的版本。
首选的替换版本是不以这种方式绑定的版本,returns 原始缓冲区指针 (withUnsafeBytes<R>(_ body: (UnsafeRawBufferPointer) throws -> R) rethrows -> R
);幸运的是,在这些之间转换只会改变你从指针读取的方式:
extension Data {
func scanValueFromData<T>(start: Int = 0, invalid: T) -> (T, Int) {
let length = MemoryLayout<T>.size
guard self.count >= start + length else {
return (invalid, start + length)
}
return (self.subdata(in: start ..< start + length).withUnsafeBytes { [=10=].load(as: T.self) }, start + length)
}
}
使用 UnsafeRawBufferPointer.load(as:)
您可以安全地从缓冲区中读取一个普通类型 T
。 (请注意,对于非平凡类型调用此方法不安全,但该方法的原始版本也是如此。)
如果想进一步简化,可以避免重复start + length
:
func scanValueFromData<T>(start: Int = 0, invalid: T) -> (T, Int) {
let length = MemoryLayout<T>.size
var value = invalid
if count >= start + length {
value = subdata(in: start ..< start + length).withUnsafeBytes { [=11=].load(as: T.self) }
}
return (value, start + length)
}
甚至更短,以可读性为代价:
func scanValueFromData<T>(start: Int = 0, invalid: T) -> (T, Int) {
let length = MemoryLayout<T>.size
let value = count >= start + length ? subdata(in: start ..< start + length).withUnsafeBytes { [=12=].load(as: T.self) } : invalid
return (value, start + length)
}