OC消息机制

2023-11-12

1 OC消息机制

OC对象调用方法在编译阶段不知道具体的方法在哪里,是在运行的过程中,向对象发送消息,通过对象得到函数地址,调用函数,如果没有找到,则抛出异常。
OC中方法调用,其实都是转成了objc_msgSend函数的调用, 给receiver 【方法调用者】 发送了一条消息 【selector 方法名】。

objc_msgSend 底层有3大阶段:

  • OC 消息发送
  • 动态方法解析
  • 消息转发

类的数据结构: 类对象中,存储着isa, superclass , 属性、对象方法、协议、成员变量等

struct objc_class {
Class isa; //类的isa指向它的metaclass
Class superclass; //指向类的超类
cache_t cache; // 方法缓存 - 方法缓存列表,散列表(哈希表)数据结构,缓存自己之前调用过的方法,指向最近使用的方法的指针,用于提升效率
class_data_bits_t; // 获取具体的类信息
}

2 OC消息发送

如何通过对象找到调用函数的地址?
[selector 方法名]会返回一个SEL变量,这个变量是char *的形式将方法对应为唯一的值,以键值对的形式存储函数地址。类对象中的isa就是指向对象的类的指针isa。

发送过程:
1、在程序运行时会给每个类的结构体分配一块空间,对象的isa指向的就是这块空间
2、当发送调用方法的消息后,根据receiver对象的isa指针获取它对应的class
3、通过SEL查找函数,优先在class的cache查找message方法,如果找不到,再到methodLists查找,若还不能找到,再去superClass中查找,找到后会将method放到对应objc_class的cache中,方便下次查找。
4、一旦找到message这个方法,再依据receiver 中的self 指针找到当前的对象,调用当前对象的具体实现的方法(IMP),然后传递参数,调用实现方法。

在这里插入图片描述

当对象收到无法解读的消息的时候,则需要启动消息转发。

1、首先判断调用的方法对象是否为nil, 如果为nil,则直接退出,通过实例对象的isa 找到类对象,在类对象的cache 列表中查找,如果找到直接调用,
2、如果cache 列表中没有,则在这个类对象的方法列表中查找,如果找到调用,并将此方法放在自己的cache 中,方便之后查找
3、如果类对象方法列表中没有,则通过类对象的superclass 指针,找到父类的类对象, 先cache 中查找,再方法列表中查看。如果在父类中找到了方法,则调用,并将方法缓存到自己的cache中,方便之后查找。
4、如果superclass 为nil, 则进入动态方法解析阶段。

3 OC动态方法解析

1、首先会判断是否进入过动态方法解析阶段,

  • 如果进入过则直接进入下一步,消息转发
  • 如果没有进入,则会进入这个方法解析阶段,会调用 - resolveInstanceMethond; 在这个方法里面实现代码,之后将这个动态方法解析阶段标记为执行过的状态。

2、动态解析过后,会重新走消息发送的流程,如果找不到方法会再次进入resolveInstanceMethond方法,此时已经标记过了,直接进入一下个阶段:消息转发

4 OC消息转发

绘图中

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

OC消息机制 的相关文章

  • 为什么在尝试编译此代码时会收到错误“错误:未知类型名称'虚拟'”?

    Code struct IRenderingEngine virtual void Initialize int width int height 0 virtual void Render const 0 virtual void Upd
  • NSCalendar 返回明年第一周上周一的错误日期

    我使用下面的代码使用随机日期来计算上周一 哪个工作文件但我的代码在明年日期中断 下面是相同的代码 NSDate date NSDate dateWithTimeIntervalSince1970 1483620311 228 NSLog c
  • 如何检测 UISwipeGestureRecognizer 的结束?

    来自苹果文档 滑动是一种离散手势 因此每个手势仅发送一次关联的操作消息 void touchesEnded NSSet touches withEvent UIEvent event 当我使用 UISwipeGestureRecognize
  • Admob 广告无法快速显示

    您好 我正在尝试将 admob 广告添加到已使用 swift 上传到应用商店的应用程序中 我在 admob 中制作了一个应用程序并复制了 appid 和广告 id 并显示了各自的横幅广告和插页式广告 这里的问题是当我写这行时 request
  • 如何在 Swift 中将文件名与文件扩展名分开?

    给定包中文件的名称 我想将该文件加载到我的 Swift 应用程序中 所以我需要使用这个方法 let soundURL NSBundle mainBundle URLForResource fname withExtension ext 无论
  • 如何开始复杂级别的跨平台移动应用开发? [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • 如何从 ContentView 外部显示 SwiftUI 警报?

    我正在构建 Swift 应用程序 并试图找出如何显示警报 我有一个单独的 swift 文件正在执行一些计算 并且在某些条件下我希望它向用户显示警报 基本上告诉他们出了问题 然而 我见过的大多数例子都要求警报在ContentView或以其他方
  • 如何保护 iOS 应用程序免受任何操作系统攻击(在越狱设备上)

    我希望保护我的应用程序数据 以防任何操作系统攻击或越狱 iOS 设备上的未经授权的访问 在这种情况下 有什么方法可以检测此类威胁并保护应用程序数据 虽然我同意 jrturton 的说法 但如果您有想要保护的关键数据免受流氓应用程序 而不是用
  • 每 24 小时触发一次方法

    我正在尝试每天在给定时间触发一个方法 我尝试了一些方法 但我无法真正使其发挥作用 任何意见 将不胜感激 此外 如果无论应用程序是否打开它都会触发 那就更理想了 这可能吗 UI本地通知 http developer apple com lib
  • ios swift parse:从 3 个类收集数据

    我有这样的结构 User CardSet 带有指向 User objectId 的指针 user 和 col name 带有点 cards 的卡片到 Card Set objectId 和列 name 我想选择所有卡数据 包括当前用户的卡集
  • 为什么 iOS 启动屏幕很慢?

    我的 iOS 应用程序启动屏幕大约需要 3 5 秒 我有一张将在启动屏幕后加载的地图 我的用户必须等待启动屏幕加载 然后再等待 3 秒才能加载地图 有没有办法最大限度地减少启动屏幕时间 基本上这种延迟意味着you在启动过程中做了一些非常错误
  • 使用未解析的标识符“FlurryAdInterstitial”

    我正在尝试整合Flurry Interstitial Ads使用cocoapods in Swift and Xcode 7 1 1 我正在关注开发人员雅虎网站上的此文档 https developer yahoo com flurry d
  • 会话重新启动后 AVcapture 会话启动缓慢

    我有一个主视图控制器 它连接到具有 avcapturesession 的第二个视图控制器 我第一次从主视图控制器转向捕获会话控制器 大约需要 50 毫秒 使用 仪器 检查 然后我从捕获会话返回到主视图控制器 然后从主控制器返回到 avcap
  • 如何向标准 UIButton 添加徽章? [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 是否可以在标准中添加看起来标准的徽章UIButton 如果不支持半原生 那么实现此目的最简单的方法是什么 示例图片 这是 Sascha
  • watchOS 错误:控制器接口描述中的未知属性

    我将 WKInterfacePicker 添加到情节提要中 并将其连接到界面控制器中的 IBOutlet 运行应用程序时 它在控制台中显示一条错误消息 控制器的接口描述 watchPicker 中的未知属性 Code interface I
  • TableViewController 的 viewDidLoad 未触发

    我一直在关注这个tutorial http www appcoda com ios programming sidebar navigation menu 有一个滑出式菜单 我添加了一个 TableViewController 它将显示文章
  • Objective-C 中发送给对象的消息可以被监听或者打印出来吗? [复制]

    这个问题在这里已经有答案了 可能的重复 Objective C 中拦截方法调用 https stackoverflow com questions 1618474 intercept method call in objective c 如
  • 如何在 UICollectionView 中将行居中?

    我有一个UICollectionView与随机细胞 有什么方法可以让我将行居中吗 默认情况下它是这样的 x x x x x x x x x x x x x x 这是所需的布局 x x x x x x x x x x x x 我必须做这样的事
  • 在 Swift 中从 Parse 加载图像

    我成功地将数据从 Parse 提取到 swift 中 但我的图像似乎没有按照我的方式工作 在我的 cellForRowAtIndexPath 方法中 我执行以下操作 var event AnyObject eventContainerArr
  • 是否可以跨 2 个不同的 iOS 应用程序访问数据?

    假设我在 App1 中存储了一些 ID 数据 并希望在同一设备上的 App2 中访问它 平台上可以这样吗 如果没有的话有什么解决方法吗 您可以使用iOS 钥匙扣 http developer apple com library ios do

随机推荐

  • vue中methods一个方法调用另外一个方法

    vue在同一个组件内 methods中的一个方法调用methods中的另外一个方法 可以在调用的时候 this options methods test2 this options methods test2 一个方法调用另外一个方法 ne
  • 今天我们来分享一下著名的分布式存储项目IPFS吧嘻嘻(最近在金融科技大赛,有相关的了解调用)

    我们先来了解一下HTTP的机制和原理吧 对于我们现在的网页协议来说 所有的HTML等前端的页面结构显示和文件都是通过HTTP请求来进行对中心化服务的访问 就像某一些时候 我们会发现自己的网页是不存在 是因为在服务器的中间无法的接受到我们的请
  • TypeScript 联合类型

    联合类型 联合类型 Union Types 可以通过管道 将变量设置多种类型 赋值时可以根据设置的类型来赋值 语法 Type1 Type2 Type3 实例 let res string number res 12 console log
  • tesseract-ocr 第四课 如何训练新语言

    tesseract 3 0x是完全可训练的 该页描述了训练过程 提供了一些指南来应用到各语言中 版权所有 转载请注明出处 并标明链接 作者 jolly wang 介绍 tesseract 3 0x是完全可训练的 该页描述了训练过程 提供了一
  • HiAI Foundation助力端侧音视频AI能力,高性能低功耗释放云侧成本

    过去三年是端侧AI高速发展的几年 华为在2020年预言了端侧AI的发展潮流 2021年通过提供端云协同的方式使我们的HiAI Foundation应用性更进一个台阶 2022年提供视频超分端到端的解决方案 在2023HDC大会上 HiAI
  • Python系列

    1 Python3的安装 一 下载Python3 7 二 安装程序 勾选添加到路径 三 安装完成 四 首次运行 无法启动 出现下面的提示 五 把C Windows SysWOW64的api ms win crt runtime l1 1 0
  • Java实现Excel转PDF的两种方法总结

    hello 你好呀 我是 一个超会写bug的程序猿 使用具将Excel转为PDF的方法有很多 在这里我给大家介绍两种常用的方法 分别应对两种不一样的使用场景 接下来我在springboot环境下给大家做一下演示 一 使用spire转化PDF
  • 【C语言】用递归法将一个整数转换成字符串。例如,输入483,应输出字符串“483”。N的位数不确定,可以是任意的整数(负数/正数)。

    程序如下 有不懂或者错误评论区留言 谢谢 include
  • 【C语言】冒泡排序

    一 算法描述 在一遍遍历的时候把最大的数放到后面 几次遍历后后面就是排序好的 经过n 1次遍历 二 冒泡排序代码 void bubble int a int n int i j t for i 1 i
  • 【ABAP系列】SAP ABAP下载带密码的Excel文件

    公众号 SAP Technical 本文作者 matinal 原文出处 http www cnblogs com SAPmatinal 原文链接 ABAP系列 SAP ABAP下载带密码的Excel文件 前言部分 大家可以关注我的公众号 公
  • upload-labs-03

    一 前言 本关涉及的是黑名单的绕过 我们先来看看什么是黑名单 黑名单 明确不让上传的文件后缀名 例如 jsp asp php html 二 环境 靶场 upload labs 工具 burpsuit 三 思路 老规矩 上传一个包含一句话木马
  • java web POI批量导出excel到zip包出错处理

    好久不见 最近在做一个导出批量excel的功能 因为不希望通过先写出单个excel到本地 然后再压缩成zip后导出 因此随手百度 找到倒流进ZipOutputStream 然后变成zip导出 demo代码如下 RequestMapping
  • 驱动模块Makefile解析

    作者 王劲南 华清远见嵌入式学院讲师 先看一下代码 ifeq KERNELRELEASE KERNELDIR home linux linux 2 6 22 6 PWD shell pwd modules MAKE C KERNELDIR
  • 读书笔记:《人工智能》

    读书笔记 摘自 人工智能 作者 李开复 王咏刚 第一章 人工智能来了 人工智能已经来了 而且它就在我们身边 几乎无处不在 人类 你好 不管我们是碳基人类还是硅基机器人 都没有本质的区别 我们中的每一员都应获得应有的尊重 每当前沿科技取得重大
  • 通过木马程序rootkit隐蔽行踪-创建root用户都删除不了的木马文件

    前沿 实战1 通过rootkit留后门 1 通过rootkit提权 2 通过rootkit隐藏木马进程号 3 通过rootkit隐藏木马文件 实战2 创建一个root用户 都删除不了的木马文件 实验环境 服务端 63 cn IP 192 1
  • 零代码实现接口自动化测试-RF框架实践

    robotframework是一款关键字自动化测试框架 可能做各种类型的自动化测试 本文介绍通过 robotframework 来实现接口测试 安装接口请求的第三方库 pip install robotframework requests
  • Unity入门03——Unity脚本

    1 脚本基本规则 1 设置编程用工具 2 基本规则 1 创建规则 不在VS中创建脚本了 可以放在Assets文件夹下的任何位置 建议同一文件夹管理 类名和文件名必须一致 不然不能挂载 因为反射机制创建对象 会通过文件名去找Type 建议不要
  • 晶圆价格计算

    昨天和一个朋友聊天 朋友提及到如果自己做芯片 成本大约为2 3元人民币 今天正好朋友圈有朋友转发此类文章 https mp weixin qq com s biz MzA4ODMwNTMxNg mid 400134208 idx 1 sn
  • download-git-repo报错128

    参考链接https segmentfault com q 1010000012493731
  • OC消息机制

    目录 1 OC消息机制 2 OC消息发送 3 OC动态方法解析 4 OC消息转发 1 OC消息机制 OC对象调用方法在编译阶段不知道具体的方法在哪里 是在运行的过程中 向对象发送消息 通过对象得到函数地址 调用函数 如果没有找到 则抛出异常