【发布时间】:2019-03-15 05:30:15
【问题描述】:
在 Swift 4 中,我正在创建一个 DSPSplitComplex 以在 vDSP_fft_zip() 中使用,但下次我创建另一个 DSPSplitComplex 时它会立即被覆盖。
(DSPSplitComplex结构有2个UnsafeMutablePointer<Float>)
//--Create the DSPSplitComplex
var A = [Float](repeating:0, count:32);
var B = [Float](repeating:0, count:32)
var splitComplex1 = DSPSplitComplex(realp: &A, imagp: &B)
//--Perform fft
log2Size = vDSP_Length(log2f(Float(32)))
setupFFT = vDSP_create_fftsetup(log2Size, FFTRadix(FFT_RADIX2))!;
vDSP_fft_zip(setupFFT, & splitComplex1, 1, log2Size, FFTDirection(FFT_FORWARD));
//--Create another DSPSplitComplex
var C = [Float](repeating:0, count:32);
var D = [Float](repeating:0, count:32)
var splitComplex2 = DSPSplitComplex(realp: &C, imagp: &D)
我现在可以在调试器中看到 splitComplex2.realp 的 UnsafeMutablePointer 与 splitComplex1.realp 的地址相同,因此我对 splitComplex2 所做的任何事情都会覆盖 splitComplex1
我猜线索可能在标题“不安全”中,但如果它实际上不可用,那么存储返回的 DSPSplitComplex 内容的正确策略是什么?
我想从它们创建新的 [Float] 数组是制作永久副本的一种方式
let arrary = Array(UnsafeBufferPointer(start: splitComplex1.realp, count: 32))
...但似乎,尽管阅读了 Swift 文档,但我仍然误解了 UnsafeMutablePointer 的意义,为什么 vDSP_fft_zip() 会返回从一开始就无法使用的东西?
【问题讨论】:
-
从它的样子来看,
DSPSplitComplex不会获取您传递给它的缓冲区的自己的副本,因此它存储了两个悬空指针(悬空是因为 inout 到指针的参数转换只产生指针在通话期间有效)。根据您的需要,您可以使用Array的withUnsafeMutableBufferPointer方法来获得对底层内存的范围访问。但是如果你需要更多的灵活性,我会考虑创建一个类包装器类型来分配必要的内存并在deinit中释放它(你可以使用ManagedBuffer来提高内存效率) -
谢谢,我明白了,使用 withUnsafeMutableBufferPointer 解决了。
标签: swift vdsp unsafemutablepointer