当前位置: 首页 > news >正文

iOS主要知识点梳理回顾-3-运行时消息机制

运行时(runtime)

        运行时是OC的重要特性,也是OC动态性的根本支撑。动态,如果利用好了,扩展性就很强。当然了,OC的动态性只能算是一个一般水平。与swift、java这种强类型校验的语言相比,OC动态性很强,和js这种纯动态的语言(随时给类增加函数、属性)相比,OC的动态性就弱很多。动态,可以帮助我们在运行时修改类的属性、函数、甚至创建一个新类

相关知识点

消息机制

        OC中的方法调用、属性读写等都是通过消息机制来处理的,当我们调用一个方法时,其实是向那个实例发送了一个消息(包含类方法,类本身是Class的实例)。所以后面的一些功能特点其实也使用了消息机制的特性,这里我们主要说说消息转发。

OC的函数调用实际上发送了一条消息,那调用过程就是消息处理过程,首先从类方法或者实例方法列表中获取你要调用的方法,如果没找到就进入转发流程。转发流程中预留了可扩展的点,大致过程是这样的

  1. 动态解析,此过程如果正确添加了方法就执行方法并结束转发,否则继续下面的步骤
  2. 备用接收者,转发给其他类/实例,如果不转发,则继续下面的步骤
  3. 完整转发,获取方法签名并转发,如果正确设置了签名并转发则结束,否则继续
  4. 调用未找到方法函数并抛出异常


动态解析

类方法动态解析(resolveClassMethod)

+ (BOOL)resolveClassMethod:(SEL)sel {NSString *selName = NSStringFromSelector(sel);NSLog(@"%s : %@", __func__, selName);if (sel == @selector(greet)) {// 动态添加 +greet 方法class_addMethod(object_getClass(self), sel, (IMP)greet1, "v@:");}return NO;
}void greet1(id self, SEL _cmd) {NSLog(@"Hello from MyClass!");
}

这里我用class_addMethod来动态添加了一个方法,方法名是greet,方法的实现指向了greet1.还应该注意到class_addMethod的第一个参数,他的类型是Class,如果写self是不生效的,需要用object_getClass(self)才可以。原因是我们要给元类增加方法,具体:

  • object_getClass(self) 返回类的 元类(meta-class),是 self 的类的类对象。
  • self和self.class 返回的是 类对象,即当前类本身。

实例方法动态解析(resolveInstanceMethod)

+ (BOOL)resolveInstanceMethod:(SEL)aSelector {if (aSelector == @selector(greet)) {class_addMethod(self, aSelector, (IMP)greet1, "v@:");}return [super resolveClassMethod:aSelector];
}

这里和类方法的创建只是第一个参数有差别,其他一样

关于返回值我没发现区别,关键还在于是不是正确的添加了方法,如果添加了则不再继续后续转发步骤,否则不论返回YES还是NO都会继续后面的步骤。

备用接收者

如果 resolveInstanceMethod(或class)没有正确的添加方法,Runtime 会调用 forwardingTargetForSelector: 方法。在这个阶段,你可以返回一个对象,如果是类方法返回类。Runtime 将会尝试将消息转发给这个对象或类,如果这个对象或类能够响应消息,消息就被解析了。后面将不再单独区分类还是实例,方法名都一样,只是+方法和-方法的区别

- (id)forwardingTargetForSelector:(SEL)aSelector {if (aSelector == @selector(greet)) {return [[OtherClass alloc] init];}return [super forwardingTargetForSelector:aSelector]; // 确保继续转发
}

完整转发

如果没有设置备用接收者,将进入最后的完整转发阶段,Runtime 会调用 methodSignatureForSelector: 方法获取方法的签名,然后再调用 forwardInvocation: 方法来处理消息。在 forwardInvocation: 中,你可以自定义消息的处理逻辑,包括选择使用哪个对象来处理消息。

- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector {return [NSMethodSignature signatureWithObjCTypes:"v@:"];
}- (void)forwardInvocation:(NSInvocation *)anInvocation {// 将消息转发给 OtherClass[anInvocation invokeWithTarget:[[OtherClass alloc] init]]; 
}

关于signature的书写规则参考:

类型编码符号
voidv
id@
SEL:
inti
floatf
doubled
char **
BOOLB
struct{name=...}
pointer (void *)^v

未找到方法

如果最终消息无法解析,以上步骤都未处理,Runtime 将会调用 doesNotRecognizeSelector: 方法,该方法默认会抛出异常,导致程序崩溃。

应用,消息机制是OC动态特性的一个体现,我们可以动态的处理函数调用,增加切入操作等。

相关文章:

iOS主要知识点梳理回顾-3-运行时消息机制

运行时(runtime) 运行时是OC的重要特性,也是OC动态性的根本支撑。动态,如果利用好了,扩展性就很强。当然了,OC的动态性只能算是一个一般水平。与swift、java这种强类型校验的语言相比,OC动态性很…...

深度学习中的Checkpoint是什么?

诸神缄默不语-个人CSDN博文目录 文章目录 引言1. 什么是Checkpoint?2. 为什么需要Checkpoint?3. 如何使用Checkpoint?3.1 TensorFlow 中的 Checkpoint3.2 PyTorch 中的 Checkpoint3.3 transformers中的Checkpoint 4. 在 NLP 任务中的应用5. 总…...

STM32开发笔记,编译与烧录

1. Keil开发环境 【Project】》【Manager】》【Pack Installer】选择相应的芯片,Unpack安装。 2. 编译 3. 烧录 烧录时,Boot0 为 1,Boot1 为 0。烧录后启动,Boot0 为 0 ,Boot 1 为 0。 3.1 ST-LINK烧录 测试连接&a…...

【CXX-Qt】1 CXX-Qt入门

与其他Qt-Rust绑定相比,CXX-Qt的目标不仅仅是将Qt功能暴露给Rust,而是完全将Rust集成到Qt生态系统中。我们将通过一个最小示例,展示如何使用CXX-Qt在Rust中创建自己的QObject,并将其与基于QML的小型GUI集成。 一、阅读前准备知识…...

JS宏进阶:XMLHttpRequest对象

一、概述 XMLHttpRequest简称XHR,它是一个可以在JavaScript中使用的对象,用于在后台与服务器交换数据,实现页面的局部更新,而无需重新加载整个页面,也是Ajax(Asynchronous JavaScript and XML)…...

物联网智能语音控制灯光系统设计与实现

背景 随着物联网技术的蓬勃发展,智能家居逐渐成为现代生活的一部分。在众多智能家居应用中,智能灯光控制系统尤为重要。通过语音控制和自动调节灯光,用户可以更便捷地操作家中的照明设备,提高生活的舒适度与便利性。本文将介绍一…...

hyperf知识问题汇总

1、简单说下 hyperf(什么是 hyperf) 答:hyperf 是一个依赖swoole扩展的 php 开源开发框架,它由黄朝辉团队设计创建维护,具备简洁而强大的组件和超强的并发性能,而且还支持微服务架构,例如&…...

制药行业 BI 可视化数据分析方案

一、行业背景 随着医药行业数字化转型的深入,企业积累了海量的数据,包括销售数据、生产数据、研发数据、市场数据等。如何利用这些数据,挖掘其价值,为企业决策提供支持,成为医药企业面临的重大挑战。在当今竞争激烈的…...

【SVN基础】

软件:ToritoiseSVN 代码版本回退:回退到上一个版本 问题:SVN版本已经提交了版本1和版本2,现在发现不需要版本2的内容,需要回退到版本1然后继续开发。 如图SVN版本已经提交到了107版本,那么本地仓库也已经…...

多项式插值(数值计算方法)Matlab实现

多项式插值(数值计算方法)Matlab实现 一. 原理介绍二. 程序设计1. 构建矩阵2. 求解矩阵方程3. 作出多项式函数4. 绘制插值曲线5. 完整代码 三. 图例 一. 原理介绍 关于插值的定义及基本原理可以参照如下索引 插值原理(数值计算方法&#xff…...

[AI]Mac本地部署Deepseek R1模型 — — 保姆级教程

[AI]Mac本地部署DeepSeek R1模型 — — 保姆级教程 DeepSeek R1是中国AI初创公司深度求索(DeepSeek)推出大模型DeepSeek-R1。 作为一款开源模型,R1在数学、代码、自然语言推理等任务上的性能能够比肩OpenAI o1模型正式版,并采用MI…...

android手机本地部署deepseek1.5B

手机本地部署大模型需要一个开源软件 Release Release v1.6.7 a-ghorbani/pocketpal-ai GitHub 下载release版本apk 它也支持ios,并且是开源的,你可以编译修改它 安装完后是这样的 可以下载推荐的模型,也可以在pc上下载好,然后copy到手机里 点 + 号加载本地模型...

理解UML中的四种关系:依赖、关联、泛化和实现

在软件工程中,统一建模语言(UML)是一种广泛使用的工具,用于可视化、设计、构造和文档化软件系统。UML提供了多种图表类型,如类图、用例图、序列图等,帮助开发者和设计师更好地理解系统的结构和行为。在UML中…...

机器学习 - 词袋模型(Bag of Words)实现文本情感分类的详细示例

为了简单直观的理解模型训练,我这里搜集了两个简单的实现文本情感分类的例子,第一个例子基于朴素贝叶斯分类器,第二个例子基于逻辑回归,通过这两个例子,掌握词袋模型(Bag of Words)实现文本情感…...

Kimi k1.5: Scaling Reinforcement Learning with LLMs

TL;DR 2025 年 kimi 发表的 k1.5 模型技术报告,和 DeepSeek R1 同一天发布,虽然精度上和 R1 有微小差距,但是文章提出的 RL 路线也有很强的参考意义 Paper name Kimi k1.5: Scaling Reinforcement Learning with LLMs Paper Reading Note…...

如何评估云原生GenAI应用开发中的安全风险(下)

以上就是如何评估云原生GenAI应用开发中的安全风险系列中的上篇内容,在本篇中我们介绍了在云原生AI应用开发中不同层级的风险,并了解了如何定义AI系统的风险。在本系列下篇中我们会继续探索我们为我们的云原生AI应用评估风险的背景和意义,并且…...

ASP.NET Core程序的部署

发布 不能直接把bin/Debug部署到生产环境的服务器上,性能低。应该创建网站的发布版,用【发布】功能。两种部署模式:“框架依赖”和“独立”。独立模式选择目标操作系统和CPU类型。Windows、Linux、iOS;关于龙芯。 网站的运行 在…...

《深度LSTM vs 普通LSTM:训练与效果的深度剖析》

在深度学习领域,长短期记忆网络(LSTM)以其出色的处理序列数据能力而备受瞩目。而深度LSTM作为LSTM的扩展形式,与普通LSTM在训练和效果上存在着一些显著的不同。 训练方面 参数数量与计算量:普通LSTM通常只有一层或较少…...

Spring依赖注入方式

写在前面:大家好!我是晴空๓。如果博客中有不足或者的错误的地方欢迎在评论区或者私信我指正,感谢大家的不吝赐教。我的唯一博客更新地址是:https://ac-fun.blog.csdn.net/。非常感谢大家的支持。一起加油,冲鸭&#x…...

Photoshop自定义键盘快捷键

编辑 - 键盘快捷键 CtrlShiftAltK 把画笔工具改成Q , 橡皮擦改成W , 涂抹工具改成E , 增加和减小画笔大小A和S 偏好设置 - 透明度和色域 设置一样颜色 套索工具 可以自定义套选一片区域 Shiftf5 填充 CtrlU 可以改颜色/色相/饱和度 CtrlE 合并图层 CtrlShiftS 另存…...

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器的上位机配置操作说明

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器专为工业环境精心打造,完美适配AGV和无人叉车。同时,集成以太网与语音合成技术,为各类高级系统(如MES、调度系统、库位管理、立库等)提供高效便捷的语音交互体验。 L…...

eNSP-Cloud(实现本地电脑与eNSP内设备之间通信)

说明: 想象一下,你正在用eNSP搭建一个虚拟的网络世界,里面有虚拟的路由器、交换机、电脑(PC)等等。这些设备都在你的电脑里面“运行”,它们之间可以互相通信,就像一个封闭的小王国。 但是&#…...

谷歌浏览器插件

项目中有时候会用到插件 sync-cookie-extension1.0.0:开发环境同步测试 cookie 至 localhost,便于本地请求服务携带 cookie 参考地址:https://juejin.cn/post/7139354571712757767 里面有源码下载下来,加在到扩展即可使用FeHelp…...

深入剖析AI大模型:大模型时代的 Prompt 工程全解析

今天聊的内容,我认为是AI开发里面非常重要的内容。它在AI开发里无处不在,当你对 AI 助手说 "用李白的风格写一首关于人工智能的诗",或者让翻译模型 "将这段合同翻译成商务日语" 时,输入的这句话就是 Prompt。…...

调用支付宝接口响应40004 SYSTEM_ERROR问题排查

在对接支付宝API的时候,遇到了一些问题,记录一下排查过程。 Body:{"datadigital_fincloud_generalsaas_face_certify_initialize_response":{"msg":"Business Failed","code":"40004","sub_msg…...

LeetCode - 394. 字符串解码

题目 394. 字符串解码 - 力扣(LeetCode) 思路 使用两个栈:一个存储重复次数,一个存储字符串 遍历输入字符串: 数字处理:遇到数字时,累积计算重复次数左括号处理:保存当前状态&a…...

家政维修平台实战20:权限设计

目录 1 获取工人信息2 搭建工人入口3 权限判断总结 目前我们已经搭建好了基础的用户体系,主要是分成几个表,用户表我们是记录用户的基础信息,包括手机、昵称、头像。而工人和员工各有各的表。那么就有一个问题,不同的角色&#xf…...

1.3 VSCode安装与环境配置

进入网址Visual Studio Code - Code Editing. Redefined下载.deb文件,然后打开终端,进入下载文件夹,键入命令 sudo dpkg -i code_1.100.3-1748872405_amd64.deb 在终端键入命令code即启动vscode 需要安装插件列表 1.Chinese简化 2.ros …...

IoT/HCIP实验-3/LiteOS操作系统内核实验(任务、内存、信号量、CMSIS..)

文章目录 概述HelloWorld 工程C/C配置编译器主配置Makefile脚本烧录器主配置运行结果程序调用栈 任务管理实验实验结果osal 系统适配层osal_task_create 其他实验实验源码内存管理实验互斥锁实验信号量实验 CMISIS接口实验还是得JlINKCMSIS 简介LiteOS->CMSIS任务间消息交互…...

什么?连接服务器也能可视化显示界面?:基于X11 Forwarding + CentOS + MobaXterm实战指南

文章目录 什么是X11?环境准备实战步骤1️⃣ 服务器端配置(CentOS)2️⃣ 客户端配置(MobaXterm)3️⃣ 验证X11 Forwarding4️⃣ 运行自定义GUI程序(Python示例)5️⃣ 成功效果![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/55aefaea8a9f477e86d065227851fe3d.pn…...