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

【转】Objective-C消息机制的原理

转自:http://dangpu.sinaapp.com/?p=119

在Objective-C中,message与方法的真正实现是在执行阶段绑定的,而非编译阶段。编译器会将消息发送转换成对objc_msgSend方法的调用。

    objc_msgSend方法含两个必要参数:receiver、方法名(即:selector),如:
    [receiver message]; 将被转换为:objc_msgSend(receiver, selector);
 
    objc_msgSend方法也能hold住message的参数,如:
    objc_msgSend(receiver, selector, arg1, arg2, …);
  
    objc_msgSend方法会做按照顺序进行以下操作,以完成动态绑定:
  1. 查找selector所指代的程序(方法的真正实现)。因为不同类对同一方法有不同的实现,所以对方法的真正实现的查找依赖于receiver的类
  2. 调用该实现,并将一系列参数传递过去
  3. 将该实现的返回值作为自己的返回值,返回之
    消息传递的关键是,编译器构建每个类和对象时所采用的数据结构。每个类都包含以下两个必要元素:
  • 一个指向父类的指针
  • 一个调度表(dispatch table)。该调度表将类的selector与方法的实际内存地址关联起来

 

    每个对象都有一个指向所属类的指针isa。通过该指针,对象可以找到它所属的类,也就找到了其全部父类,如下图所示:
 
    当向一个对象发送消息时,objc_msgSend方法根据对象的isa指针找到对象的类,然后在类的调度表(dispatch table)中查找selector。如果无法找到selector,objc_msgSend通过指向父类的指针找到父类,并在父类的调度表(dispatch table)中查找selector,以此类推直到NSObject类。一旦查找到selector,objc_msgSend方法根据调度表的内存地址调用该实现。通过这种方式,message与方法的真正实现在执行阶段才绑定。
 
    为了保证消息发送与执行的效率,系统会将全部selector和使用过的方法的内存地址缓存起来。每个类都有一个独立的缓存,缓存包含有当前类自己的selector以及继承自父类的selector。查找调度表(dispatch table)前,消息发送系统首先检查receiver对象的缓存。
  缓存命中的情况下,消息发送(messaging)比直接调用方法(function call)只慢一点点点点。

转载于:https://www.cnblogs.com/gatsbywang/p/5165819.html

相关文章:

  • ASP.NET MVC URL Routing 学习
  • Unsupported repository,resources names are not uri
  • POJ-3034 Whac-a-Mole 动态规划
  • Android客户端采用Http 协议Post方式请求与服务端进行数据交互
  • 约定一种格式,通过约定的格式来实现一些动作,以达到作者的目的。--程序...
  • Oracle创建索引必知——献给数据库开发者
  • 友友系统:让云计算更加贴近用户
  • 同时展多个物料BOM List
  • RHEL6入门系列之十四,用户和组的基本知识
  • easyui-datagrid 报错:TypeError: col is null
  • 腾讯调整移动事业群,王小川送马化腾一记归属
  • swift学习笔记之UILabel
  • js解析与序列化json数据(二)
  • SVN的标准目录结构:trunk、branches、tags
  • 读取文件
  • 「前端早读君006」移动开发必备:那些玩转H5的小技巧
  • android百种动画侧滑库、步骤视图、TextView效果、社交、搜房、K线图等源码
  • Dubbo 整合 Pinpoint 做分布式服务请求跟踪
  • JavaScript异步流程控制的前世今生
  • Linux链接文件
  • Linux中的硬链接与软链接
  • nginx 配置多 域名 + 多 https
  • Python爬虫--- 1.3 BS4库的解析器
  • Quartz初级教程
  • react-native 安卓真机环境搭建
  • Selenium实战教程系列(二)---元素定位
  • Shadow DOM 内部构造及如何构建独立组件
  • Vue官网教程学习过程中值得记录的一些事情
  • vue数据传递--我有特殊的实现技巧
  • Zepto.js源码学习之二
  • 服务器之间,相同帐号,实现免密钥登录
  • 关于Android中设置闹钟的相对比较完善的解决方案
  • 关于List、List?、ListObject的区别
  • 前端设计模式
  • 前端学习笔记之原型——一张图说明`prototype`和`__proto__`的区别
  • 如何设计一个微型分布式架构?
  • 深入浅出Node.js
  • 思否第一天
  • 移动端唤起键盘时取消position:fixed定位
  • 自动记录MySQL慢查询快照脚本
  • ​ 无限可能性的探索:Amazon Lightsail轻量应用服务器引领数字化时代创新发展
  • (C++17) std算法之执行策略 execution
  • (html转换)StringEscapeUtils类的转义与反转义方法
  • (libusb) usb口自动刷新
  • (PWM呼吸灯)合泰开发板HT66F2390-----点灯大师
  • (八)c52学习之旅-中断实验
  • (二)WCF的Binding模型
  • (机器学习-深度学习快速入门)第一章第一节:Python环境和数据分析
  • (免费领源码)Java#ssm#MySQL 创意商城03663-计算机毕业设计项目选题推荐
  • (五) 一起学 Unix 环境高级编程 (APUE) 之 进程环境
  • (一)python发送HTTP 请求的两种方式(get和post )
  • (已解决)什么是vue导航守卫
  • (转)3D模板阴影原理
  • .net core Swagger 过滤部分Api
  • .NET MAUI学习笔记——2.构建第一个程序_初级篇