取消引用 UnsafeMutablePointer<UnsafeMutableRawPointer>

Dereference UnsafeMutablePointer<UnsafeMutableRawPointer>

我有一个正在传递数据的块,我想将其转换为浮点数组——例如[[0.1,0.2,0.3, 1.0], [0.3, 0.4, 0.5, 1.0], [0.5, 0.6, 0.7, 1.0]]。该数据以 data:UnsafeMutablePointer<UnsafeMutableRawPointer> 的形式传递给我(内部数组是 RGBA 值)

fwiw -- 块参数来自 SCNParticleEventBlock

如何将数据解引用到 [[Float]] 中?一旦我有了包含内部数组的数组,我就可以引用内部数组 (colorArray) 数据:

let rgba: UnsafeMutablePointer<Float> = UnsafeMutablePointer(mutating: colorArray)
let count = 4
for i in 0..<count {
    print((rgba+i).pointee)
}

fwiw -- 这是 Apple 的示例 Objective-C 引用数据的代码 (from SCNParticleSystem handle(_:forProperties:handler:) )

[system handleEvent:SCNParticleEventBirth
      forProperties:@[SCNParticlePropertyColor]
          withBlock:^(void **data, size_t *dataStride, uint32_t *indices , NSInteger count) {
              for (NSInteger i = 0; i < count; ++i) {
                  float *color = (float *)((char *)data[0] + dataStride[0] * i);
                  if (rand() & 0x1) { // Switch the green and red color components.
                      color[0] = color[1];
                      color[1] = 0;
                  }
              }
          }];

基于,我在swift中编写了粒子系统处理函数:

    ps.handle(SCNParticleEvent.birth, forProperties [SCNParticleSystem.ParticleProperty.color]) {
    (data:UnsafeMutablePointer<UnsafeMutableRawPointer>, dataStride:UnsafeMutablePointer<Int>, indicies:UnsafeMutablePointer<UInt32>?, count:Int) in

    for i in 0..<count {

        // get an UnsafeMutableRawPointer to the i-th rgba element in the data
        let colorsPointer:UnsafeMutableRawPointer = data[0] + dataStride[0] * i

        //  convert the UnsafeMutableRawPointer to a typed pointer by binding it to a type:
        let floatPtr = colorsPointer.bindMemory(to: Float.self, capacity: dataStride[0])
        // convert that to a an  UnsafeMutableBufferPointer
        var rgbaBuffer = UnsafeMutableBufferPointer(start: floatPtr, count: dataStride[0])
        // At this point, I could convert the buffer to an Array, but doing so copies the data into the array and any changes made in the array are not reflected in the original data.  UnsafeMutableBufferPointer are subscriptable, nice.
        //var rgbaArray = Array(rgbaBuffer)

        // about half the time, mess with the red and green components
        if(arc4random_uniform(2) == 1) {
            rgbaBuffer[0] = rgbaBuffer[1]
            rgbaBuffer[1] = 0
        }
    }
 }

我真的不确定这是否是解决此问题的最直接方法,并且与 objective-C 代码相比似乎相当麻烦(参见上面的问题)。我当然愿意接受其他解决方案 and/or 对此解决方案的评论。

您实际上可以为键入的 UnsafeMutablePointer 添加下标,而无需创建 UnsafeMutableBufferPointer,如:

let colorsPointer:UnsafeMutableRawPointer = data[0] + dataStride[0] * i
let rgbaBuffer = colorsPointer.bindMemory(to: Float.self, capacity: dataStride[0])
if(arc4random_uniform(2) == 1) {
    rgbaBuffer[0] = rgbaBuffer[1]
    rgbaBuffer[1] = 0
}

您是否曾经让您的解决方案发挥作用?似乎只有少数 SCNParticleProperties 可以在 SCNParticleEventBlock 块中使用。