美文网首页
[Swift拓展]2、结构体与类

[Swift拓展]2、结构体与类

作者: 史记_d5da | 来源:发表于2024-03-23 15:45 被阅读0次

    1、关键字mutating

    通过SIL对比一下添加mutating和不添加的两者区别

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

    Xcode配置执行脚本命令
    swiftc -emit-sil ${SRCROOT}/LGSwiftTest/main.swift > ./main.sil
    打开main.sil文件

    // func test
    sil hidden @$s4main5PointV4testyyF : $@convention(method) (Point) -> () 
    debug_value %0 : $Point, let, name "self", argno 1, implicit // id: %1
    // func moveBy
    sil hidden @$s4main5PointV6moveBy1x1yySd_SdtF : $@convention(method) (Double, Double, @inout Point) -> () 
    
    

    SIL 文档的解释
    An @inout parameter is indirect. The address must be of an initialized object.(当前参数 类型是间接的,传递的是已经初始化过的地址)
    总结:
    异变方法的本质:对于变异方法, 传入的 self 被标记为 inout 参数。无论在 mutating 方法 内部发生什么,都会影响外部依赖类型的一切。
    输入输出参数:如果我们想函数能够修改一个形式参数的值,而且希望这些改变在函数结束之后 依然生效,那么就需要将形式参数定义为 输入输出形式参数 。在形式参数定义开始的时候在前边 添加一个 inout关键字可以定义一个输入输出形式参数

    2、函数调用

    2.1、函数调用

    1、函数的地址空间是连续的。
    看一下如下函数调用

    class LGTeacher{ //继承关系吗?没有
        //消息调度的机制 
        func teach(){
            print("teach")
        }
        func teach1(){
            print("teach1")
        }
        func teach2(){
            print("teach2")
        }
    }
    let t = LGTeacher()
    t.teach()
    t.teach1()
    t.teach2()
    
    汇编执行过程
    si

    从上述汇编和si可以看出,函数的地址空间是连续的,teach函数的调用过程:找到 Metadata 基于函数表的调度确定函数地址(metadata + 偏移量), 执行函数,函数存放的位置为vtable中。

    2.2、@_dynamicReplacement 方法替换

    class LGTeacher { 
        dynamic func teach(){
            print("teach")
        }
    }
    extension LGTeacher {
        @_dynamicReplacement(for: teach)
        func teach3() {
            print("tech3333")
        }
    }
    

    编译后的sil文件

    // LGTeacher.teach3()
    sil hidden [dynamic_replacement_for "$s14ViewController9LGTeacherC5teachyyF"] [ossa] @$s14ViewController9LGTeacherC6teach3yyF : $@convention(method) 
    

    最终方法teach3()被替换为teach()

    相关文章

      网友评论

          本文标题:[Swift拓展]2、结构体与类

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