如何将 array.withUnsafeMutableBufferPointer 从 swift 2 迁移到 swift 3?

How to migrate array.withUnsafeMutableBufferPointer from swift 2 to swift 3?

我想使用来自 this link 的代码 这是 swif 2

public protocol SGLImageType {
    typealias Element
    var width:Int {get}
    var height:Int {get}
    var channels:Int {get}
    var rowsize:Int {get}
    
    func withUnsafeMutableBufferPointer(
        @noescape body: (UnsafeMutableBufferPointer<Element>) throws -> Void
    ) rethrows
}

a class 在协议之上实现:

final public class SGLImageRGBA8 : SGLImageType { ... public func withUnsafeMutableBufferPointer(@noescape body: (UnsafeMutableBufferPointer<UInt8>) throws -> Void) rethrows {
    try array.withUnsafeMutableBufferPointer(){
        // This is unsafe reinterpret cast. Be careful here.
        let st = UnsafeMutablePointer<UInt8>([=14=].baseAddress)
        try body(UnsafeMutableBufferPointer<UInt8>(start: st, count: [=14=].count*channels))
    }
}

在swift 3,第let st = UnsafeMutablePointer<UInt8>([=15=].baseAddress)行抛出这个错误:

'init' is unavailable: use 'withMemoryRebound(to:capacity:_)' to temporarily view memory as another layout-compatible type

如何解决这个错误?

您可以将 UnsafeMutableBufferPointer<UInt8> 转换为 UnsafeMutableRawBufferPointer,将其绑定到 UInt8 并从中创建一个 UnsafeMutableBufferPointer<UInt8>(此处对所有属性使用虚拟值) :

final public class SGLImageRGBA8 : SGLImageType {
    public var width: Int = 640
    public var height: Int = 480
    public var channels: Int = 4
    public var rowsize: Int = 80
    public var array:[(r:UInt8,g:UInt8,b:UInt8,a:UInt8)] =
        [(r:UInt8(1), g:UInt8(2), b:UInt8(3), a:UInt8(4))]

    public func withUnsafeMutableBufferPointer(body: @escaping (UnsafeMutableBufferPointer<UInt8>) throws -> Void) rethrows {
        try array.withUnsafeMutableBufferPointer(){ bp in
            let rbp = UnsafeMutableRawBufferPointer(bp)
            let p = rbp.baseAddress!.bindMemory(to: UInt8.self, capacity: rbp.count)
            try body(UnsafeMutableBufferPointer(start: p, count: rbp.count))
        }
    }
}

SGLImageRGBA8().withUnsafeMutableBufferPointer { (p: UnsafeMutableBufferPointer<UInt8>) in
    print(p, p.count)
    p.forEach { print([=10=]) }
}

打印

UnsafeMutableBufferPointer(start: 0x000000010300e100, count: 4) 4
1, 2, 3, 4

有关详细信息,请参阅 UnsafeRawPointer Migration and SE-0107