编译器为结构体自动生成可以传入数值的初始化器 类的定义与结构体类似, 但是编译器并没有为类自动生成可以传入成员值的初始化器
结构体和类的本质区别 结构体是值类型(枚举也是值类型) 类是引用类型 (指针类型)
size 是指针变量 size 对象的内存地址
栈空间的其中一个位置,存储的是对象的内存地址,地址指向的是堆空间中的位置 堆空间分配内存地址大小
内存地址分析,可以得到 call 也就是strct 不生成对应的 alloc malloc 实例化方法
- callq 0x100002ae0 ; Test.testClassAndStruct() -> ()
atmain.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就生成了一块堆空间 对象本身也是需要内存空间的 */