Swift(十四)-内存绑定

3,083 阅读2分钟

「这是我参与2022首次更文挑战的第22天,活动详情查看:2022首次更文挑战

内存绑定

Swift中提供了三种不同的api绑定/重新绑定指针:

  • assumingMemoryBound(to:)
  • bindMemory(to: capacity:)
  • withMemoryRebound(to: capacity: body:)

assumingMemoryBound

我们定义一个方法如下:

func testPoint(_ p: UnsafePointer<Int>) {
    print(p)
}

如果我们想要掉用这个方法,就需要传入一个类型指针;但是我们只有原生指针,这样应该如何操作呢?比如下面代码:

image.png

由于testPoint方法如要一个Int类型指针,而我们的尾随闭包中是一个元组类型的指针,直接传递将会报错!这个时候我们就需要使用assumingMemoryBound进行指针绑定:

image.png

  • 首先通过UnsafeRawPointertuplePtr转换成一个原生指针
  • 然后通过assumingMemoryBound将其绑定成Int类型;

如果我们只有原生指针,或者需要操作的两个指针类型相似,我们不想通过一系列的指针转换操作,这个时候我们就可以使用assumingMemoryBound来告诉编译器,我们类型相同,不用在做检查了;

assumingMemoryBound的本质是绕过编译器检查,实质上没有做操作;

bindMemory

bindMemory用来绑定当前的内存信息;在上述代码中,我们可以通过使用bindMemory来实现同样的结果:

image.png

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类型的,两个指针类型不匹配,这个时候怎么办呢?

image.png

我们可以通过withMemoryRebound将内存绑定为Int8.self类型,该操作只在当前作用域内生效;

withMemoryRebound就是用来临时更改当前内存绑定的类型

以上为Swift中常见的内存绑定的三种方式,在开发中灵活运用将会大大减少代码的复杂转换过程;