「这是我参与2022首次更文挑战的第22天,活动详情查看:2022首次更文挑战」
内存绑定
在Swift中提供了三种不同的api来绑定/重新绑定指针:
assumingMemoryBound(to:)bindMemory(to: capacity:)withMemoryRebound(to: capacity: body:)
assumingMemoryBound
我们定义一个方法如下:
func testPoint(_ p: UnsafePointer<Int>) {
print(p)
}
如果我们想要掉用这个方法,就需要传入一个类型指针;但是我们只有原生指针,这样应该如何操作呢?比如下面代码:
由于testPoint方法如要一个Int类型指针,而我们的尾随闭包中是一个元组类型的指针,直接传递将会报错!这个时候我们就需要使用assumingMemoryBound进行指针绑定:
- 首先通过
UnsafeRawPointer将tuplePtr转换成一个原生指针; - 然后通过
assumingMemoryBound将其绑定成Int类型;
如果我们只有原生指针,或者需要操作的两个指针类型相似,我们不想通过一系列的指针转换操作,这个时候我们就可以使用assumingMemoryBound来告诉编译器,我们类型相同,不用在做检查了;
assumingMemoryBound的本质是绕过编译器检查,实质上没有做操作;
bindMemory
bindMemory用来绑定当前的内存信息;在上述代码中,我们可以通过使用bindMemory来实现同样的结果:
与assumingMemoryBound的区别之处在于assumingMemoryBound是绕过编译器的检查,而bindMemory是直接将类型进行了转化,将UnsafePointer<(Int, Int)>类型的指针转换成了UnsafePointer<Int>类型;
bindMemory就是用来改变当前内存绑定的类型
withMemoryRebound
我们来看下边示例代码:
func testPoint(_ p: UnsafePointer<Int8>) {
}
let Uint8Ptr = UnsafePointer<UInt8>.init(bitPattern: 10)
testPoint方法需要接受一个Int8类型的指针,而我们创建的Uint8Ptr是一个Uint8类型的,两个指针类型不匹配,这个时候怎么办呢?
我们可以通过withMemoryRebound将内存绑定为Int8.self类型,该操作只在当前作用域内生效;
withMemoryRebound就是用来临时更改当前内存绑定的类型
以上为Swift中常见的内存绑定的三种方式,在开发中灵活运用将会大大减少代码的复杂转换过程;