取消引用 UnsafeMutablePointer<UnsafeMutableRawPointer>

Posted

技术标签:

【中文标题】取消引用 UnsafeMutablePointer<UnsafeMutableRawPointer>【英文标题】:Dereference UnsafeMutablePointer<UnsafeMutableRawPointer> 【发布时间】:2017-06-10 18:40:07 【问题描述】:

我有一个正在传递数据的块,我想将它转换为浮点数组的数组——例如[[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&lt;UnsafeMutableRawPointer&gt; 的形式传递给我(内部数组为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;
                  
              
          ];

【问题讨论】:

【参考方案1】:

您实际上可以为键入的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 块内使用。

【讨论】:

基于this answer,您还必须设置particleSystem.particleColorVariation = SCNVector4(x: 0, y: 0, z: 0, w: 1) 或类似值才能使粒子颜色更改生效。【参考方案2】:

基于this answer,我在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 代码相比似乎相当麻烦(请参阅上面的问题)。我当然愿意接受其他解决方案和/或此解决方案的 cmets。

【讨论】:

以上是关于取消引用 UnsafeMutablePointer<UnsafeMutableRawPointer>的主要内容,如果未能解决你的问题,请参考以下文章

如何将 UnsafeMutablePointer<UnsafeMutablePointer<Int8>?> 转换为 UnsafeMutablePointer<Unsafe

Swift:无法将“UnsafeMutablePointer”类型的值转换为预期的参数类型“UnsafeMutablePointer”

如何转换 UnsafePointer<UnsafeMutablePointer<Float>>?到 UnsafeMutablePointer<UnsafeMutableP

UnsafeMutablePointer<Float> 到 UnsafeMutablePointer<_>

如何用 arg 编写块。 Swift 闭包中的“UnsafeMutablePointer<UnsafeMutablePointer<Float>>”

如何将该 UnsafeMutablePointer<UnsafeMutablePointer<Float>> 变量转换为 AudioBufferList?