ios - Swift 缓冲区指针和数组索引
问题描述
我有以下代码:
public struct HistogramData {
var red:[vImagePixelCount] = []
var green:[vImagePixelCount] = []
var blue: [vImagePixelCount] = []
var alpha: [vImagePixelCount] = []
}
然后我按如下方式访问它:
var data: HistogramData
...
let red:UnsafeMutablePointer<vImagePixelCount> = UnsafeMutablePointer(mutating: data.red)
let green:UnsafeMutablePointer<vImagePixelCount> = UnsafeMutablePointer(mutating: data.green)
let blue:UnsafeMutablePointer<vImagePixelCount> = UnsafeMutablePointer(mutating: data.blue)
上述行不正确,XCode 显示悬空指针的警告。所以我将代码修改为:
data.red.withUnsafeMutableBufferPointer { redPtr in
data.green.withUnsafeMutableBufferPointer { greenPtr in
data.blue.withUnsafeMutableBufferPointer { bluePtr in
let red = redPtr.baseAddress!
let green = greenPtr.baseAddress!
let blue = bluePtr.baseAddress!
for i in 0..<256 {
if red[i] > maxR {
maxR = red[i]
}
if green[i] > maxG {
maxG = green[i]
}
if blue[i] > maxB {
maxB = blue[i]
}
}
...
}
即使上面的代码有效,但我不确定我们是否可以在 Swift 中的 baseAddress 上使用数组索引。正确的方法可能是将内存绑定到一定的大小,但是当数组的大小没有指定时,bindMemory 是如何工作的呢?如果上面的代码是错误的,我该如何修复(即使它可能有效,但它可能不正确)?
解决方案
你的代码是正确的。
someArray.withUnsafeMutableBufferPointer { bufPtr in ... }
使用引用数组的(可变)元素存储来调用闭包,UnsafeMutableBufferPointer
并且已经绑定到元素的类型。仅当您想以不同类型访问内存时才需要重新绑定。
然后两者都bufPtr[i]
访问bufPtr.baseAddress![i]
第 i 个数组元素(通过resp.的subscript
方法)。唯一的区别是前者在调试模式下对索引进行边界检查。UnsafeMutableBufferPointer
UnsafeMutablePointer
在优化的代码中,两种下标方法都可以访问元素存储而无需进行边界检查。这可能是一种提高性能的方法(以安全为代价)。
如果你的这部分代码对性能至关重要,并且不安全的访问真的比“正常”的数组访问快,我建议进行基准测试。
推荐阅读
- mongodb - mongodb - 管道阶段规范对象必须只包含一个字段。- 关于创建视图
- javascript - React Chrome 扩展错误:未捕获的 SyntaxError:无法在模块外使用 import 语句
- python - 非归一化自协方差函数
- airflow - Airflow - 如何处理异步 API 调用?
- java - Firebase 管理 SDK - java.lang.NoClassDefFoundError
- wordpress - 附属 WP - 推荐的修改
- python - 如何使 FuncAnimation 动画更快?
- python - 为什么我在pycharm和IDLE中运行同一个程序会得到不同的结果?
- python - 停止气流回填运行
- c++ - 关于运算符 + 重载