iOS - swift 类与结构体 方法的派发

异变方法

Swift 中 class 和 struct 都能定义方法。但是有一点区别的是默认情况 下,值类型属性不能被自身的实例方法修改。

struct Point {
    var x = 0.0, y = 0.0
    // 编译时会报错
    func moveBy(x deltaX: Double, y deltaY: Double) {
        //self
        self.x += deltaX 
        self.y += deltaY
    } 
    
}

moveBy由于修改了自身,所以会编译不通过 需要在前面加mutating

struct Point {
    var x = 0.0, y = 0.0
   mutating  func moveBy(x deltaX: Double, y deltaY: Double) {
        self.x += deltaX 
        self.y += deltaY
    } 
    
}

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

在结构体中:函数默认self是以值类型传入,加了mutating之后self是指针的方式传入

方法的调度

  • OC:使用objc_msgSend
  • swift:找到Metadata,确定函数地址(Metadata + 偏移量),执行函数,基于函数表的调度

方法调度方式

类型            调度方式    extension
值类型          静态派发    静态派发
类              函数表派发  静态派发
NSObject子类    函数表派发  静态派发

静态派发:直调调用函数地址

影响函数派发方式

  • final:添加了final关键字的函数无法被重写,使用静态派发,不会再v-table中出现,且对objc运行时不可见
  • dynamic:函数均可添加dynamic关键字,为非objc类和值类型函数赋予动态性,但派发方式还是函数表派发
  • @objc:该关键字可以将Swift函数暴露给objc运行时,依旧是函数表派发
  • @objc + dynamic:消息派发方式(OC消息传递)

在原swift中是没有runtime的,除非加了@objc

你可能感兴趣的:(iOS - swift 类与结构体 方法的派发)