微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Swift缓冲区指针和数组索引

如何解决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个数组元素(通过subscriptUnsafeMutableBufferPointer的{​​{1}}方法)。唯一的区别是,前者在调试模式下会对索引进行边界检查。

在优化的代码中,两个下标方法都无需限制检查即可访问元素存储。 可以是一种提高性能的方法(以安全为代价)。

我建议测试一下代码的这一部分是否对性能至关重要,以及不安全的访问是否真的比“常规”数组访问快。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。