Swift 中的方法调用机制

Swift 方法调用详解:与 Objective-C 的对比、V-Table 机制、Witness Table 机制

在 iOS 开发中,Swift 和 Objective-C 是两种常用的编程语言。尽管它们都能用于开发应用程序,但在方法调用的底层机制上存在显著差异。本文将详细介绍 Swift 的方法调用机制,重点对比 Objective-C 的实现,并深入探讨虚表(V-Table)和 Witness Table 机制。

目录
  1. 方法调用机制概述
  2. Swift 与 Objective-C 的方法调用对比
  3. Swift 的虚表(V-Table)机制
  4. Swift 的 Witness Table 机制
  5. 性能与灵活性的权衡
  6. 总结

1. 方法调用机制概述

方法调用是编程语言中最基本的操作之一,不同语言和实现方式会对方法调用的性能和灵活性产生深远影响。了解底层机制可以帮助开发者优化代码性能和理解语言特性。


2. Swift 与 Objective-C 的方法调用对比

Objective-C 方法调用

Objective-C 是一种动态语言,方法调用依赖于运行时系统,通过消息传递(message passing)机制实现。每次方法调用都通过 objc_msgSend 进行动态分派:

[object doSomething];

会被编译器转换为:

objc_msgSend(object, @selector(doSomething));

这种机制极大地提高了灵活性,可以在运行时改变对象的行为,但也带来了运行时开销。

Swift 方法调用

Swift 更倾向于静态绑定和编译时优化,减少了运行时开销。对于大多数实例方法调用,Swift 会在编译时确定调用目标,直接生成调用指令。所有实例方法默认都是虚方法,这意味着它们可以在继承链中被子类重写,并且调用时会进行动态分派:

class BaseClass {
    func doSomething() {
        print("Base implementation")
    }
}

class SubClass: BaseClass {
    override func doSomething() {
        print("Subclass implementation")
    }
}

let object: BaseClass = SubClass()
object.doSomething()  // 输出 "Subclass implementation"

在这个示例中,doSomething 是一个实例方法,默认是虚方法。即使通过 BaseClass 类型引用 object 调用 doSomething,实际执行的仍然是 SubClass 中的实现。这是通过虚表(V-Table)实现的动态分派。

对于类方法和静态方法,Swift 使用静态分派,这些方法在编译时确定,不涉及运行时的动态分派。

class MyClass {
    class func classMethod() {
        print("Class method")
    }

    static func staticMethod() {
        print("Static method")
    }
}

MyClass.classMethod()  // 输出 "Class method"
MyClass.staticMethod() // 输出 "Static method"

3. Swift 的虚表(V-Table)机制

虚表(V-Table)机制

在面向对象的编程中,虚表(V-Table)是一种用于支持多态的动态分派机制。每个类都有一个虚表,存储该类的所有虚方法(virtual methods)的指针。对象在调用方法时,通过虚表找到对应的实现。

实现原理

当一个类定义了虚方法或重写了父类的方法时,编译器会在该类的虚表中插入相应的方法指针。对象在调用方法时,会通过虚表进行动态分派:

class BaseClass {
    func doSomething() {
        print("Base implementation")
    }
}

class SubClass: BaseClass {
    override func doSomething() {
        print("Subclass implementation")
    }
}

let object: BaseClass = SubClass()
object.doSomething()  // 输出 "Subclass implementation"

在这个例子中,doSomething 方法调用会通过虚表进行分派,调用 SubClass 的实现。


4. Swift 的 Witness Table 机制

Witness Table 机制

Witness Table 是 Swift 用于协议的动态分派机制。当一个类型遵循某个协议时,编译器生成一个 Witness Table,存储该类型对协议中所有方法和属性的具体实现。

实现原理

当通过协议调用方法时,Swift 使用 Witness Table 查找具体实现:

protocol MyProtocol {
    func doSomething()
}

class MyClass: MyProtocol {
    func doSomething() {
        print("MyClass implementation of doSomething")
    }
}

let object: MyProtocol = MyClass()
object.doSomething()

编译器会为 MyClass 生成一个 Witness Table,调用 object.doSomething() 时,通过 Witness Table 找到具体实现并调用。


5. 性能与灵活性的权衡

性能

Swift 的方法调用更倾向于静态绑定和编译时确定,减少了运行时的动态查找开销。虚表和 Witness Table 提供了一种高效的动态分派机制,比 Objective-C 的消息传递机制性能更优。

灵活性

Objective-C 的运行时机制极大地增强了语言的灵活性,可以在运行时动态修改类和方法。Swift 更注重类型安全和编译时优化,尽管在灵活性上有所牺牲,但在性能和安全性上有显著优势。


6. 总结

Swift 和 Objective-C 在方法调用机制上的差异反映了它们各自的设计哲学。Objective-C 强调动态性和灵活性,通过运行时消息传递实现动态分派;而 Swift 更注重静态安全和性能,通过虚表和 Witness Table 实现高效的动态分派。了解这些底层机制有助于开发者更好地优化代码和理解语言特性,从而在开发中做出更明智的选择。


希望本文对你理解 Swift 和 Objective-C 方法调用的底层机制有所帮助。如果你有任何问题或建议,欢迎留言讨论!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/773139.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

CD4017 – 带解码输出的十进制计数器

CD4017 IC 是一个十进制计数器,它有 10 个输出,分别代表 0 到 9 的数字。计数器在(14号引脚)每个时钟脉冲上升时增加 1。计数器达到 9 后,它会在下一个时钟脉冲时从 0 重新开始。 引脚名称管脚 #类型描述VD…

【常用工具】Linux命令行Restful接口调试神器——curl脚本

最近的工作经常要涉及到在Linux服务器端和外部系统联调接口,由于Postman无法在命令行使用,这里浅记一个curl脚本模板: #!/bin/bash # 请求标题 TITLE # token信息 TOKEN # url信息 URL # 请求方式 METHODPOST # Restful请求报文 BODYecho -e…

暑假学习DevEco Studio第2天

学习目标: 掌握页面跳转 学习内容: 跳转页面 创建页面: 在“project”窗口。打开“entry>src>main>ets”,右击“pages”,选择“New>ArkTS File”,命名“Second”,点击回车键。 在页面的路由&#xff0…

Go语言--函数类型、匿名函数和闭包

在Go语言中,函数也是一种数据类型,我们可以通过 type 来定义它,它的类型就是所有拥有相同的参数,相同的返回值的一种类型。 语法 通过type给函数类型起名,然后通过名字进行函数的调用 好处:多态 通过统…

【营销策划模型大全】私域运营必备

营销策划模型大全:战略屋品牌屋、电商运营模型、营销战略、新媒体运营模型、品牌模型、私域运营模型…… 该文档是一份策划总监工作模型的汇总,包括战略屋/品牌屋模型、营销战略模型、品牌相关模型、电商运营模型、新媒体运营模型和私域运营模型等&…

​​服务拆分的原则

目录 一、单一职责原则 二、服务自治原则 三、单向依赖 一、单一职责原则 单⼀职责原则原本是面向对象设计中的⼀个基本原则, 它指的是⼀个类应该专注于单⼀功能. 不要存在多于⼀个导致类变更的原因 在微服务架构中, ⼀个微服务也应该只负责⼀个功能或业务领域, 每个服务应该…

C++ | Leetcode C++题解之第216题组合总和III

题目&#xff1a; 题解&#xff1a; class Solution { private:vector<vector<int>> res;void backtracking(int k, int n, vector<int> ans){if(k 0 || n < 0){if(k 0 && n 0){res.emplace_back(ans);}return;}int start (ans.size() 0 ?…

恒创科技:HTTP错误码403禁止意味着什么,怎么修复它?

HTTP错误码403禁止意味着客户端无权访问特定网页或服务器。403 错误表示客户端存在问题&#xff0c;无论用户使用的是哪种网络浏览器&#xff0c;都可能发生这种情况。幸运的是&#xff0c;阻止服务器允许访问特定页面的问题通常可以修复。以下是一些常见原因和相应的解决方案。…

【Android源码】Gerrit安装

前言 如果你打开 https://android.googlesource.com/platform/manifest&#xff0c;就会发现&#xff0c;google官方管理Android源码&#xff0c;使用的是Gerrit。Android系统源码是非常大的&#xff0c;用Git肯定是不适合。对于大型项目&#xff0c;得用Gerrit&#xff0c;今…

背包问题(一)

一.P3985 不开心的金明(01背包变式) 解析: 一开始没有看数据范围,直接当01背包直接写了,结果最后4个测试点RE,一看到数据范围就老实了,1e9的数据,数组直接炸,所以不能直接使用一维的01背包.看了一下题解,部分人是通过极差对数据进行分类,按照300进行分开,使用贪心和dp一起做. …

7_1_SVPWM概述

1、SPWM 正弦脉宽调制法&#xff08;SPWM&#xff09;是将每一正弦周期内的多个脉冲作自然或规则的宽度调制&#xff0c;使其依次调制出相当于正弦函数值的相位角和面积等效于正弦波的脉冲序列&#xff0c;形成等幅不等宽的正弦化电流输出。 通过调整占空比使等效电流近似为正弦…

DT浏览器很好用

DT浏览器是一款简单的浏览器&#xff0c;又是强大的浏览器&#xff0c;界面简洁大方&#xff0c;软件使用流畅。DT浏览器的网址收藏&#xff0c;人工智能写作&#xff0c;书法笔记等功能与众不同。DT浏览器的图文识别功能和笔记本搭配使用&#xff0c;可以对内容编辑修改和保存…

时序模型综述论文

时序模型综述论文&#xff1a; A Survey of Time Series Foundation Models: Generalizing Time Series Representation with Large Language Model

c++ String

1.string类 还记得我们数据结构学的串吗&#xff0c;现在在c中&#xff0c;我们有了c提供的标准库&#xff0c;它是一个写好的类&#xff0c;非常方便使用 1. string是表示字符串的字符串类 2. 该类的接口与常规容器的接口基本相同&#xff0c;再添加了一些专门用来操作strin…

学习笔记——动态路由——OSPF工作原理(SPF算法)

3、SPF算法 SPF算法(最短路径优先算法&#xff0c;也称Dijkstra算法)由荷兰科学家狄克斯特拉于1959年提出的。 SPF算法将每一个路由器作为根(ROOT)来计算其到每一个目的地路由器的距离&#xff0c;每一个路由器根据一个统一的数据库会计算出路由域的拓扑结构图&#xff0c;该…

MySQL:MySQL总结

文章目录 MySQL思维导图基础实际在 Innodb 存储引擎中&#xff0c;会用一个特殊的记录来标识最后一条记录&#xff0c;该特殊的记录的名字叫 supremum pseudo-record &#xff0c;所以扫描第二行的时候&#xff0c;也就扫描到了这个特殊记录的时候&#xff0c;会对该主键索引加…

基于Bootstrap Blazor开源的.NET通用后台权限管理系统

前言 今天大姚给大家分享一个基于Bootstrap Blazor开源的.NET通用后台权限管理系统&#xff0c;后台管理页面兼容所有主流浏览器&#xff0c;完全响应式布局&#xff08;支持电脑、平板、手机等所有主流设备&#xff09;&#xff0c;可切换至 Blazor 多 Tabs 模式&#xff0c;…

JVM原理(十六):JVM虚拟机类型擦除与泛型发展

1. 泛型 泛型的本质是参数化类型或者参数化多态的应用&#xff0c;即可以将操作的数据类型指定为方法签名中的一种特殊参数&#xff0c;这种参数类型能够用在类、接口和方法的创建中&#xff0c;分别构成泛型类、泛型接口和泛型方法。 泛型让程序员能够以针对泛化的数据类型编…

手动访问mongo和ES插入和查询

1、手动访问mongo 1.1、mongo连接数据库 1.2、mongo插入和查询 db.hmf_test.insert( { "aoeId": "1", "aoeAes": "吴秀梅", "aoeSm4": "北京xx网络技术有限公司.", "aoeSm4_a": "…

【BUUCTF-PWN】4-ciscn_2019_n_1

参考&#xff1a;BUUCTF-ciscn_2019_n_1 - 纸鸢asahi - 博客园 (cnblogs.com) buuctf 刷题记录_PWN ciscn_2019_n_1 - MuRKuo - 博客园 (cnblogs.com) 从题海中入门&#xff08;四&#xff09;ciscn_2019_n_1 - FreeBuf网络安全行业门户 ciscn_2019_n_1 ——两种解法_0x4134800…