问题描述
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个数组元素(通过subscript
或UnsafeMutableBufferPointer
的{{1}}方法)。唯一的区别是,前者在调试模式下会对索引进行边界检查。
在优化的代码中,两个下标方法都无需限制检查即可访问元素存储。 可以是一种提高性能的方法(以安全为代价)。
我建议测试一下代码的这一部分是否对性能至关重要,以及不安全的访问是否真的比“常规”数组访问快。