汇编分析结构体、内存、闭包

111 阅读3分钟

编译器为结构体自动生成可以传入数值的初始化器 类的定义与结构体类似, 但是编译器并没有为类自动生成可以传入成员值的初始化器

结构体和类的本质区别 结构体是值类型(枚举也是值类型) 类是引用类型 (指针类型)

size 是指针变量 size 对象的内存地址

栈空间的其中一个位置,存储的是对象的内存地址,地址指向的是堆空间中的位置 堆空间分配内存地址大小

内存地址分析,可以得到 call 也就是strct 不生成对应的 alloc malloc 实例化方法

  • callq 0x100002ae0 ; Test.testClassAndStruct() -> () at main.swift:2
  • Test`init() in Point #1 in testClassAndStruct():
  • -> 0x100002b80 <+0>: pushq %rbp
  • 0x100002b81 <+1>:  movq   %rsp, %rbp
    
  • 0x100002b84 <+4>:  xorps  %xmm0, %xmm0
    
  • 0x100002b87 <+7>:  movaps %xmm0, -0x10(%rbp)
    
  • 0x100002b8b <+11>: movq   $0x3, -0x10(%rbp)
    
  • 0x100002b93 <+19>: movq   $0x4, -0x8(%rbp)
    
  • 0x100002b9b <+27>: movl   $0x3, %eax
    
  • 0x100002ba0 <+32>: movl   $0x4, %edx
    
  • 0x100002ba5 <+37>: popq   %rbp
    
  • 0x100002ba6 <+38>: retq   
    

class Size { var x = 1 var y = 2 }

var size = Size()

0x100002b42 <+34>: callq 0x100002b80
; Size.__allocating_init() -> Size in Test.testClassAndStruct() -> () at main.swift:7`

进入slowAlloc 的内容 malloc 内容进行调用

证明是向堆空间申请内存

对象的堆空间类的本质区别 Size 指针变量指向的内存大小,是一个8/字节,用来指向堆空间的内存地址

值类型 值类型 赋值给var let 或者给函数传参,直接将所有内从拷贝一份 类似对文件进行copy ,产生了全新的文件副本,属于深拷贝

swift 的标准库中,为了提升性能 String Set 采用了copy on write的方法,只有当开始修改的时候,才开始进行内存地址修改 仅当有写操作的时候,才会真正执行拷贝操作

值类型的赋值操作 可以覆盖对应的内存信息,

引用类型的赋值操作

值类型,引用类型的let 也就是值类型不可以修改,值类型的内存不可以修改,struct内存存储所有的值内容 因此他内容全部不可以修改

引用类型 S class的内存不可以修改, class的内存中,存放的东西不可以修改 但是Class的属性内容可以修改

对象的堆空间申请过程 class_getclassInstance 类对象一共有多少内存申请

方法占用对象的内存吗? 方法不占用对象的内存 方法存储在哪里? 方法,函数存储在代码段

打印出来地址值,如果中间1后面不是四个0的时候,大概是存放在堆空间的

闭包表达式 (Closure Expression) { //in 前面放 参数等类型 , //in 后面放执行代码 (参数代码) -> 返回值类型 in 函数体代码 }

闭包:一个函数和它所捕获的常量/变量环境组合起来,称为闭包 ~一般指捕获的外部的函数 ~ 一般它捕获的是外层函数的变量-常量

可以把闭包想象成一个类的实例对象, 内存存储在堆空间,由于调用了alloc的方法 捕获的局部变量/常量就是对象的成员 组成的闭包的函数就是类内部定义的方法 不同的闭包实例对象 进行了变量捕获,栈空间和堆空间都存在一个num 但是由于plus捕获了num 因此就存储了一个堆空间的值

``typealias Fn = (Int) -> Int func getFn() -> Fn { var num = 0 func plus(_ i:Int) -> Int{ num += i return num } return plus }

var fn = getFn()``

/** 1:getFn 将函数存放在对应的数据内段 闭包产生了alloc 调用 主要是存放num 的值 申请了对应的堆空间,因此访问了对应的内存空间 调用了一次FN就生成了一块堆空间 对象本身也是需要内存空间的 */