什么是不安全的可变指针<Void>?如何修改底层内存?



我正在尝试使用SpriteKit的SKMutableTexture类,但我不知道如何使用UnsafeMutablePointer< Void >。我有一个模糊的想法,它是指向内存中一系列字节数据的指针。但是我该如何更新它呢?这在代码中会是什么样子?

编辑

下面是一个要使用的基本代码示例。我该如何让它做一些简单的事情,比如在屏幕上创建一个红色方块?

    let tex = SKMutableTexture(size: CGSize(width: 10, height: 10))
    tex.modifyPixelDataWithBlock { (ptr:UnsafeMutablePointer<Void>, n:UInt) -> Void in
        /* ??? */
    }

来自SKMutableTexture.modifyPixelDataWithBlock:的文档

假设纹理字节被存储为紧密压缩的32bpp,8bpc(无符号整数)RGBA像素数据。您提供的颜色分量应该已经乘以alpha值。

因此,当你得到一个void*时,底层数据是以4x8比特流的形式存在的。

你可以操纵这样一个结构:

// struct of 4 bytes
struct RGBA {
    var r: UInt8
    var g: UInt8
    var b: UInt8
    var a: UInt8
}
let tex = SKMutableTexture(size: CGSize(width: 10, height: 10))
tex.modifyPixelDataWithBlock { voidptr, len in
    // convert the void pointer into a pointer to your struct
    let rgbaptr = UnsafeMutablePointer<RGBA>(voidptr)
    // next, create a collection-like structure from that pointer
    // (this second part isn’t necessary but can be nicer to work with)
    // note the length you supply to create the buffer is the number of 
    // RGBA structs, so you need to convert the supplied length accordingly...
    let pixels = UnsafeMutableBufferPointer(start: rgbaptr, count: Int(len / sizeof(RGBA))
    // now, you can manipulate the pixels buffer like any other mutable collection type
    for i in indices(pixels) {
        pixels[i].r = 0x00
        pixels[i].g = 0xff
        pixels[i].b = 0x00
        pixels[i].a = 0x20
    }
}

UnsafeMutablePointer<Void>是Swift中void*的等价物-指向任何东西的指针。您可以访问底层内存作为其memory属性。通常,如果您知道底层类型是什么,您将首先强制指向该类型的指针。然后,您可以使用下标来访问内存中的特定"插槽"。

例如,如果数据实际上是UInt8值的序列,您可以说:

let buffer = UnsafeMutablePointer<UInt8>(ptr)

现在可以访问各个UIInt8值,如buffer[0]buffer[1]等。