OC和Swift的区别,发送消息和执行方法的区别

在 Objective-C 和 Swift 中,方法调用的机制存在显著的区别,具体体现在消息传递和方法调用上。以下是关于这两种机制的详细说明:

Objective-C:发送消息

消息传递机制

Objective-C 使用消息传递(Message Passing)机制来调用方法。这意味着在运行时,方法调用被转化为发送消息给对象。在编译时,编译器不会直接确定调用哪个方法,而是在运行时查找对应的实现。

[object doSomething];

消息传递的细节
  • 动态性:在运行时确定方法的实现,这使得 Objective-C 非常灵活,可以实现方法交换、动态添加方法等高级特性。
  • 运行时库:Objective-C 有一个强大的运行时库(Runtime Library),负责查找方法的实现、处理消息传递等。
// 发送消息的底层实现
objc_msgSend(object, @selector(doSomething));

优点
  • 灵活:可以在运行时动态改变对象的行为。
  • 动态绑定:可以实现更复杂的设计模式,如代理、观察者模式。
缺点
  • 性能开销:由于在运行时查找方法实现,性能上有一定的开销。
  • 类型安全:由于动态性,编译时类型检查较弱,可能导致运行时错误。

Swift:方法调用

方法调用机制

Swift 使用静态绑定(Static Dispatch)和动态绑定(Dynamic Dispatch)两种方式来调用方法。默认情况下,Swift 使用静态绑定,这意味着在编译时确定方法的实现,直接调用方法地址。

object.doSomething()

方法调用的细节
  • 静态绑定:编译时确定方法的实现,直接调用方法地址,性能更高。        
    • 非类方法:如结构体和枚举的方法。
    • 没有被标记为 @objc 的类方法
    • final 方法:被标记为 final 的方法,不能被子类重写。
  • 动态绑定:通过使用 @objc 关键字或协议,可以实现类似于 Objective-C 的动态绑定。
// 静态绑定
class MyClass {func doSomething() {print("Doing something")}
}let object = MyClass()
object.doSomething()

// 动态绑定
class MyClass: NSObject {@objc func doSomething() {print("Doing something")}
}let object = MyClass()
object.perform(#selector(MyClass.doSomething))

优点
  • 性能高:默认使用静态绑定,方法调用速度快。
  • 类型安全:编译时进行类型检查,减少运行时错误。
缺点
  • 灵活性:相比 Objective-C,动态性较弱,但可以通过 @objc 和 dynamic 关键字实现动态特性。

对比总结

特性Objective-CSwift
方法调用方式消息传递(Message Passing)静态绑定(Static Dispatch)
动态绑定(Dynamic Dispatch)
灵活性高:运行时确定方法实现低:默认编译时确定方法实现
性能较低:运行时查找方法实现有开销较高:编译时确定方法实现
类型安全较低:编译时检查较弱较高:编译时类型检查
实现动态特性简单:原生支持复杂:需要使用 @objc 和 dynamic 关键字
运行时特性强大:丰富的运行时库支持较弱:但可以通过 @objc 和运行时特性扩展
常见用途动态代理、方法交换、运行时修改行为高性能方法调用、类型安全编程

具体应用场景

  • Objective-C 更适合那些需要大量动态特性、运行时行为修改的场景,如动态代理、方法交换、运行时添加方法等。
  • Swift 更适合那些需要高性能、类型安全的场景,如大部分日常应用开发、需要高效执行的代码路径等。如果需要动态特性,可以通过 @objc 和 dynamic 关键字来实现。

代码示例

Objective-C 消息传递
#import <Foundation/Foundation.h>@interface MyClass : NSObject
- (void)doSomething;
@end@implementation MyClass
- (void)doSomething {NSLog(@"Doing something in Objective-C");
}
@endint main(int argc, const char * argv[]) {@autoreleasepool {MyClass *object = [[MyClass alloc] init];[object doSomething];  // 消息传递}return 0;
}

Swift 方法调用
import Foundationclass MyClass {func doSomething() {print("Doing something in Swift")}
}let object = MyClass()
object.doSomething()  // 静态绑定

Swift 动态绑定
import Foundationclass MyClass: NSObject {@objc func doSomething() {print("Doing something in Swift with dynamic dispatch")}
}let object = MyClass()
object.perform(#selector(MyClass.doSomething))  // 动态绑定

通过这些代码示例,可以清晰地看到 Objective-C 和 Swift 在方法调用机制上的区别。理解这些区别,将有助于开发者在不同的场景下选择合适的语言和方法调用方式。

Swift 的方法调用机制主要分为静态绑定和动态绑定:

  • 静态绑定:在编译时确定方法实现,性能较高,适用于结构体、枚举和 final 方法。
  • 动态绑定:在运行时通过虚方法表或 Objective-C 运行时确定方法实现,适用于类的继承层次和需要动态特性的场景。

理解这些机制,有助于编写高效且健壮的 Swift 代码,并在需要时合理使用动态特性。

详细说明

Swift 的方法调用机制主要通过静态绑定(Static Dispatch)和动态绑定(Dynamic Dispatch)来实现。了解这些机制的原理,有助于编写高效且健壮的 Swift 代码。以下是对 Swift 方法调用原理的详细解释:

1. 静态绑定(Static Dispatch)

静态绑定也称为直接调用(Direct Dispatch),在编译时就确定了方法的具体实现,并直接调用方法地址。静态绑定通常用于以下情况:

  • 非类方法:如结构体和枚举的方法。
  • 没有被标记为 @objc 的类方法
  • final 方法:被标记为 final 的方法,不能被子类重写。
示例
struct MyStruct {func doSomething() {print("Doing something")}
}let myStruct = MyStruct()
myStruct.doSomething()  // 静态绑定

在这个例子中,doSomething 方法在编译时就确定了具体实现,编译器会直接调用该方法的地址,这种方式性能较高。

2. 动态绑定(Dynamic Dispatch)

动态绑定在运行时确定方法的具体实现。Swift 中,动态绑定主要通过两种方式实现:

  • 虚方法表(V-Table):用于类的方法调用。
  • Objective-C 运行时:通过 @objc 和动态特性实现。
2.1 虚方法表(V-Table)

在类的继承层次中,Swift 会使用虚方法表来实现动态绑定,这与 C++ 的虚方法表类似。每个类都有一个虚方法表,记录了该类的方法实现地址。在方法调用时,通过虚方法表查找具体的实现地址。

class ParentClass {func doSomething() {print("Doing something in ParentClass")}
}class ChildClass: ParentClass {override func doSomething() {print("Doing something in ChildClass")}
}let parent: ParentClass = ChildClass()
parent.doSomething()  // 动态绑定,通过虚方法表查找具体实现

在这个例子中,doSomething 方法在运行时通过虚方法表查找具体实现,因为 parent 引用类型是 ParentClass,但实际对象是 ChildClass

2.2 Objective-C 运行时

通过使用 @objc 关键字,Swift 可以与 Objective-C 运行时交互,实现类似于 Objective-C 的消息传递机制。

import Foundationclass MyClass: NSObject {@objc func doSomething() {print("Doing something in Swift with dynamic dispatch")}
}let myClass = MyClass()
myClass.perform(#selector(MyClass.doSomething))  // 动态绑定,通过 Objective-C 运行时查找方法实现

在这个例子中,doSomething 方法被标记为 @objc,因此可以通过 Objective-C 的运行时机制进行动态绑定。

3. 方法调用的优化

Swift 编译器在方法调用时会进行多种优化,以提高性能:

  • 内联(Inlining):对于短小且频繁调用的方法,编译器可能会内联方法的实现,避免函数调用的开销。
  • 去虚拟化(Devirtualization):在某些情况下,编译器可以确定具体的类型,从而将动态绑定转换为静态绑定。
  • 专用化(Specialization):对于泛型方法,编译器可以生成特定类型的实现,提高性能。

4. 使用 dynamic 关键字

Swift 提供了 dynamic 关键字,用于显式指定方法使用动态绑定。这通常用于需要动态特性的场景,如 KVO(键值观察)和 Objective-C 运行时特性。

class MyClass: NSObject {@objc dynamic func doSomething() {print("Doing something dynamically")}
}

总结

Swift 的方法调用机制主要分为静态绑定和动态绑定:

  • 静态绑定:在编译时确定方法实现,性能较高,适用于结构体、枚举和 final 方法。
  • 动态绑定:在运行时通过虚方法表或 Objective-C 运行时确定方法实现,适用于类的继承层次和需要动态特性的场景。

理解这些机制,有助于编写高效且健壮的 Swift 代码,并在需要时合理使用动态特性。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

go语言进阶 init() 函数

go 语言包 在一个项目中通常我们需要引入第三方包&#xff0c;我们来看下 当我们导入一个包的时候 发生了什么&#xff1a; 首先我们先详细介绍下两个函数&#xff1a; init(), main() 是 go 语言中的保留函数。我们可以在源码中 定义 init()函数&#xff0c; 此函数会在包导入…

iPhone录音的m4a格式音频文件怎么转成MP3格式?

在日常工作生活中&#xff0c;我们有时会用电脑或手机录音&#xff0c;比如iPhone录音的M4A格式音频&#xff0c;要上传至某些软件或者平台使用&#xff0c;但是有时这些平台或者软件对音频格式有要求&#xff0c;比如有的就只能上传mp3格式的文件。 这个时候我们就需要先将音频…

【Python Cookbook】S01E19 在字符串的开头或者结尾处做文本匹配

目录 问题解决方案讨论 问题 如果我们需要在字符串的开头或者结尾处按照指定的文本模式做检查&#xff0c;例如检查文件的扩展名&#xff0c;URL协议类型等等。 解决方案 检查如扩展名等结尾的文本模式&#xff0c;选择 str.startswith() 方法&#xff0c;检查如URL协议类型…

unity 制作表格 配置

using System.Collections; using System.Collections.Generic; using UnityEngine; [CreateAssetMenu(fileName “exeConfig.asset”, menuName “Config/exeConfig”, order 3)] public class exeConfig : ScriptableObject { public string carName; [Header("表名…

基础IO(上)

前言 文件 内容 属性 所有对文件的操作就是对内容操作和对属性操作。内容是数据&#xff0c;属性也是数据。存储文件&#xff0c;必须既存储内容又存储数据。创建文件默认就是在磁盘中的。我们要访问一个文件的时候&#xff0c;都是要先把这个文件打开的。访问文件的本质就是…

无人机EasyDSS推拉流视频直播技术在农业植保中的精准应用与展望

随着科技的飞速发展&#xff0c;无人机在农业领域的应用越来越广泛&#xff0c;特别是在农业植保方面&#xff0c;无人机以其独特的优势&#xff0c;为农业生产带来了革命性的改变。 无人机在农业植保中的应用主要体现在两个方面&#xff1a;提高工作效率和精准喷洒药物。在以…

每天认识一家仪器仪表厂商 | 横河测试测量官网 - Yokogawa

横河Yokogawa工商信息&#xff1a; 横河测量技术(上海)有限公司于2000年08月09日成立。法定代表人山崎正晴(YAMAZAKI MASAHARU)&#xff0c;公司经营范围包括&#xff1a;从事测量科技、机电科技领域内技术开发、技术转让、技术咨询、技术服务&#xff0c;仪器仪表、通讯设备、…

专业130+总分400+四川大学951信号与系统考研经验川大电子信息与通信工程,真题,大纲,参考书。教材。

今年四川大学951信号与系统专业课130&#xff08;据我所知没有140以上的今年&#xff09;&#xff0c;总分400&#xff0c;顺利上岸川大&#xff0c;回顾一下自己这一年的复习&#xff0c;希望自己的经历可以对大家复习有所借鉴&#xff0c;也是对自己的考研画上句话。专业课&a…

全屋智能的本质是低成本的重构

全屋智能&#xff08;这里指的不是每个电器都可以在APP上控制&#xff0c;而是基于场景化的全屋智能&#xff09;&#xff0c;我第一次去圣都总部听讲的时候是不准备做的&#xff08;我的理解是这玩意儿带来的是至少十万的成本&#xff09;。但随着对于装修各项事物的接触&…

使用from…import语句导入模块

自学python如何成为大佬(目录):https://blog.csdn.net/weixin_67859959/article/details/139049996?spm1001.2014.3001.5501 在使用import语句导入模块时&#xff0c;每执行一条import语句都会创建一个新的命名空间&#xff08;namespace&#xff09;&#xff0c;并且在该命名…

性格测试.

文章目录 大五人格MBTI九型人格性格测试网站 大五人格 “大五人格"理论&#xff0c;也被称为"五因素模型”&#xff08;Five-Factor Model, FFM&#xff09;或"人格大五结构模型"&#xff0c;是现代心理学中最为广泛接受的人格理论之一。它认为人格特质可…

爬虫案例实战

文章目录 一、窗口切换实战二、京东数据抓取 一、窗口切换实战 案例实战&#xff1a;使用selenium实现打开百度和腾讯两个窗口并切换 知识点&#xff1a;用到selenium中execute_script()执行js代码及switch_to.window()方法 全部代码如下&#xff1a; import time import war…

路由懒加载

在 Vue.js 中&#xff0c;路由懒加载&#xff08;也称为代码分割&#xff09;是一种优化策略&#xff0c;它允许你将 Vue 组件分割成不同的代码块&#xff0c;并在需要时按需加载它们。这有助于减少初始加载时间&#xff0c;提高用户体验。 Vue Router 支持 Webpack 的动态 im…

57.void指针(万能指针)

目录 一.什么是void指针 二.视频教程 一.什么是void指针 在定义变量的时候&#xff0c;需要用到变量的类型&#xff0c;变量的类型在表示在内存中的大小&#xff0c;而void是空&#xff0c;表示的是无类型。所以如果用void来定义一个变量会发生错误&#xff08;无法在内存中挖…

mysql中InnoDB存储引擎的Buffer Pool

大家好。众所周知&#xff0c;对于使用InnoDB作为存储引擎的表来说&#xff0c;不管是用于存储用户数据的索引&#xff08;包括聚簇索引和二级索引&#xff09;&#xff0c;还是各种系统数据&#xff0c;都是存储在磁盘上的。在处理客户端的请求时&#xff0c;当需要访问某个页…

思维导图——幕布

一、前言 幕布是一款专注于简化和组织信息的大纲笔记应用&#xff0c;它旨在帮助用户高效地整理知识点、优化工作流程以及规划个人生活。 二、软件特点 幕布工具的核心优势在于其能够快速将用户的输入转换成清晰的思维导图&#xff0c;便于视觉化地理解和记忆信息。 幕布还具…

插入mysql报错:Incorrect string value: ‘\xF0\xAC\x8C\x97\xE5\x9E...‘

原因分析 这个错误通常发生在使用MySQL数据库时&#xff0c;尝试将包含四字节UTF-8字符&#xff08;通常表示为Unicode码点大于UFFFF的字符&#xff09;插入到一个不支持这种字符的字符集列中。一般在插入睡眠emoji表情时容易遇到 解决 -- 设置数据库编码utf8mb4 ALTER DAT…

TrollInstallerX小白一键安装巨魔商店 分分钟安装成功

概述 TrollInstallerX 是一款通用的 TrollStore 安装程序。它注重可靠性和易用性。它的速度也非常快&#xff0c;能够在几秒钟内将 TrollStore 和/或其持久性助手安装到最新设备上。 TrollInstallerX 支持所有运行 iOS 14.0 - 16.6.1 的设备&#xff0c;包括 arm64 和 arm64e。…

若依分离版—增加通知公告预览及缩放功能

若依分离版—增加通知公告预览及缩放功能 前言开发通知公告 前言 若依分离版的通知公告没有预览功能&#xff0c;想开发通知公告功能 开发通知公告 效果如下 具体开发内容 修改若依notice代码如下。 <template><div class"app-container"><el-…

103.网络游戏逆向分析与漏洞攻防-ui界面的设计-加速功能的开关设计

免责声明&#xff1a;内容仅供学习参考&#xff0c;请合法利用知识&#xff0c;禁止进行违法犯罪活动&#xff01; 如果看不懂、不知道现在做的什么&#xff0c;那就跟着做完看效果&#xff0c;代码看不懂是正常的&#xff0c;只要会抄就行&#xff0c;抄着抄着就能懂了 内容…