美文网首页ios底层原理
swift指针&内存管理-内存绑定

swift指针&内存管理-内存绑定

作者: erlich | 来源:发表于2022-11-22 04:57 被阅读0次

swift提供了3种不同的API来绑定/重新绑定指针

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

绕过编译器检查 - assumingMemoryBound

就是假定内存绑定

func testPointer(_ p: UnsafePointer<Int>) {
    print(p)
}
let tuple = (30, 40)
withUnsafePointer(to: tuple) { (tuplePtr: UnsafePointer<(Int, Int)>) in
    testPointer(UnsafeRawPointer(tuplePtr)
    .assumingMemoryBound(to: Int.self))
}
image.png

其实 两者本质没什么区别,都是指向内存的指针

UnsafePointer<Int> 指向1块Int内存

UnsafePointer<Int, Int> 指向一个元组tuple内存, 也就是一块连续的内存,包含连个连续的Int

两者都是首地址

一种方式就是不 强转 UnsafePointer<Int, Int> 为 UnsafePointer<Int>

  1. 先把 元组指针转换成原始指针 UnsafeRawPointer(tuplePtr)
  2. 原始指针调用 assumingMemoryBound 绑定成Int 指针 UnsafeRawPointer(tuplePtr).assumingMemoryBound(to: Int.self)
func testPointer(_ p: UnsafePointer<Int>) {
    print(p[0])
    print(p[1])
}
let tuple = (30, 40)
withUnsafePointer(to: tuple) { (tuplePtr: UnsafePointer<(Int, Int)>) in
    testPointer(UnsafeRawPointer(tuplePtr).assumingMemoryBound(to: Int.self))
}

结果

30

40

assumingMemoryBound的意义在于:

有时候不想做指针类型转换来增加代码的复杂度

就可以调用 此api绕过编译器检查,但是并没有发生实际的指针转换

内存转换 - bindMemory

实际发生了转换,改变当前内存指针绑定的类型

func testPointer(_ p: UnsafePointer<Int>) {
    print(p[0])
    print(p[1])
}
let tuple = (30, 40)
withUnsafePointer(to: tuple) { (tuplePtr: UnsafePointer<(Int, Int)>) in
    testPointer(UnsafeRawPointer(tuplePtr)
    .bindMemory(to: Int.self, capacity: 1))
}

结果

30

40

bindMemory - 相比于assumingMemoryBound,就是改变内存绑定类型

临时改变内存绑定 - withMemoryRebound

func testPointer(_ p: UnsafePointer<Int8>) {
    print(p)
}

let UInt8Ptr = UnsafePointer<UInt8>.init(bitPattern: 30)
UInt8Ptr?.withMemoryRebound(to: Int8.self, capacity: 1, 
    { (Int8Ptr: UnsafePointer<Int8>) in
    testPointer(Int8Ptr)
})

结果

0x000000000000001e

withMemoryRebound意义在于:

临时改变内存绑定,出了api 尾随闭包作用域之后,绑定就不存在了

最后,补充一个小tip

也许你会对swift 闭包 函数的语法形式感觉会不习惯,编译器也会自动直接转变为函数体

其实高级语言语法习惯仅仅就是一种语法而已

底层其实是函数栈的形式

一个函数 包括 函数名(也就是方法指针),多个参数,函数体(包含多个变量与调用)

内存表达函数的方式就是栈的形式:

入栈顺序: 函数指针,参数顺序入栈,函数体内部逐行顺序入栈

按照这个逻辑,最后一个尾随闭包参数就可以直接变为函数体,这样并不影响函数栈的入栈方式

相关文章

  • swift指针&内存管理-内存绑定

    swift提供了3种不同的API来绑定/重新绑定指针 assumingMemoryBound(to:) bindM...

  • C 指针内存管理

    // C 指针的内存管理 // C 指针在 Swift中被冠以 unsafe 的另一个是无法对其进行自动的内存管理...

  • Swift 指针&内存管理

    指针 为什么说指针不安全 比如我们在创建一个对象的时候,是需要在堆分配内存空间的。但是这个内存空间的声明周期是有限...

  • Swift指针&内存管理

    一、指针    1、指针类型   Swift中的指针分为两类:指定数据类型的指针(typed pointer);未...

  • Swift指针|内存管理

    一、Swift指针 1.Swift指针简介 swift中的指针分为两类 typed pointer 指定数据类型指...

  • 4-1 内存管理

    1.内存布局 2.iOS内存管理方案 [isa指针保存了内存管理的信息] 2.iOS内存管理方案 [isa指针...

  • swift--指针与内存绑定

    指针 Swift中的指针分为两类, typed pointer指定数据类型指针,raw pinter未指定数据类型...

  • OC内存管理

    内存管理的方式 为什么要管理内存 内存问题体现在两个-----内存溢出、野指针异常。 内部溢出 野指针异常 内存管...

  • swift指针操作

    swift官方不建议使用指针,为了安全起见,而且使用比较麻烦,内存必须自己管理 1、直接创建指针 2、获取指针 可...

  • swift指针&内存管理-闭包的循环引用

    swift指针&内存管理-引用[https://www.jianshu.com/p/841c726e0036] 无...

网友评论

    本文标题:swift指针&内存管理-内存绑定

    本文链接:https://www.haomeiwen.com/subject/usloxdtx.html