TLDR
使文本数组可变(使用var 而不是let)并使用withUnsafeMutableBytes
var texArray = Array<SIMD4<Float>>(repeating: SIMD4<Float>(repeating: 0), count: 1)
texArray.withUnsafeMutableBytes { texArrayPtr in
texture.getBytes(texArrayPtr.baseAddress!, bytesPerRow: (MemoryLayout<SIMD4<Float>>.size * texture.width), from: region, mipmapLevel: 0)
}
说明
引入警告是因为编译器无法确保支持指针的数据不会被释放。假设您有一个函数(例如用 C 实现)来操作一些指向的数据。
func f(_ a: UnsafeMutablePointer<Int>){
a[0] = 42
}
然后必须确保在调用结束之前内存没有被释放。所以当以下面的方式调用这个函数是不安全的
var a: = [1]
p: UnsafeMutablePointer<Int>(&a)
// at this point the compiler may optimise and deallocate 'a' since it is not used anymore
f(p)
据我所知,目前这不是问题,因为局部变量不会在作用域结束之前被释放。
可以通过以下方式引入嵌套范围来说明可能的问题
var p: UnsafeMutablePointer<Int>?
do {
var a = [1]
p = UnsafeMutablePointer<Int>(&a)
} // "a" will be deallocated here
// now "p" is a dangling pointer the compiler warned you of
var b = [0] // compiler will use same memory as for "a", so manipulating memory of "p" won't segfault
f(p!) // manipulate memory
print(b[0]) // prints 42 although "b" was initialised to 0
由于b 分配的内存与a 之前使用的内存相同,因此b 的内存通过调用f(p!) 被修改。所以b[0] 是 42,尽管它被初始化为 0 并且没有显式修改。
有了这张图,应该很清楚为什么 Swift 数组上有方法 withUnsafeMutableBytes 和 withUnsafeMutableBufferPointer 以及全局函数 withUnsafeMutablePointer 以及不可变的变体。 (我个人觉得必须在数组上使用方法和在结构上使用全局函数,这让我感到困惑。)
这些函数确保不会在闭包范围内释放(或重用)内存(我还通过一些示例创建了gist)。