如何将 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。
我想使用来自 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。