swift类与结构体

101 阅读1分钟

一 异变方法 (mutating关键字)

`struct Point{

    var x :Float

    var y :Float

  mutating  func makeAdd (_ x1:Float, _ y1 :Float) {

        self.x += x1;

        self.y += y1

    }

}

var p = Point(x: 10, y: 20)

p.makeAdd(1, 1)`

以上代码执行命令 swiftc main.swift -emit-sil 生成中间代码,可以看到

截屏2021-12-28 下午3.57.03.png 如果不加mutating关键字,生成 的sil文件是这样的

截屏2021-12-28 下午4.10.30.png。 说明@inout 使得Point变得可变。

SIL 文档的解释 An @inout parameter is indirect. The address must be of an initialized object.(当前参数类型是间接的,传递的是已经初始化过的地址)

异变方法的本质:对于变异方法, 传入的 self 被标记为 inout 参数。无论在 mutating 方法内部发生什么,都会影响外部依赖类型的一切。

二 函数调度

class LGTeacher{

    func teach(){

        print("teach")

    } }

extension LGTeacher{

    func teach1(){

        print("teach1")

    }

}

var t = LGTeacher()

t.teach()

t.teach1()

通过sil

截屏2021-12-28 下午4.31.42.png可知,类中的方法是通过函数表调用的

截屏2021-12-28 下午4.40.55.png 可知,extension中的方法通过是直接调用

如果LGTeacher用struct修饰 截屏2021-12-28 下午4.57.26.png 可知,结构体的方法是是直接派发调用

final关键字 class LGTeacher{

  final  func teach(){

        print("teach")     }

} var t = LGTeacher()

t.teach()

截屏2021-12-28 下午5.08.50.png

截屏2021-12-28 下午5.09.03.png vtable中并没有teach方法,通过汇编可知是直接调用。

通过类似的方法可知,@objc关键字和dynamic走的都是函数表查找调用

但是@objc + dynamic走的是消息派发

截屏2021-12-28 下午5.20.52.png