《Objective-C Direct Methods》学习笔记
原文通过对Objective-C发展史、Objective-C中Runtime的动态派发,C语言的直接派发进行铺垫介绍,引出了direct methods这个“新特性”(文章写于2019年)。
定义
看起来是个OC的方法,却和C方法一样,当被调用时,他是会直接使用而不是通过objc_msgSend
。
使用方法
- 声明/定义
针对@interface
的成员变量或者方法的做法:
@interface MyClass: NSObject
@property(nonatomic) BOOL dynamicProperty;
@property(nonatomic, direct) BOOL directProperty;
- (void)dynamicMethod;
- (void)directMethod __attribute__((objc_direct));
@end
除了一个一个添加上去的做法,如果对@interface
所有方法和成员属性添加,用objc_direct_members
属性,使用之后,除了之前被此类声明的所有方法和成员属性之外,都会被认为是直接派发。
__attribute__((objc_direct_members))
@interface MyClass ()
@property (nonatomic) BOOL directExtensionProperty;
- (void)directExtensionMethod;
@end
对于@implementation
,也是用objc_direct_members
,不是先前声明的成员也会被认为是直接派发(包括implicit methods
)。
__attribute__((objc_direct_members))
@implementation MyClass
- (BOOL)directProperty {…}
- (void)dynamicMethod {…}
- (void)directMethod {…}
- (void)directExtensionMethod {…}
- (void)directImplementationMethod {…}
@end
动态方法不能在子类重写成直接方法
反之,直接方法也不能被重写成动态方法
协议不可以声明直接方法
反之,类不能以直接方法的形式实现协议方法
- 调用
之前已经提到,direct method
看起来跟OC一样,实际上使用的方法也跟OC一样。
MyClass *object = [[[MyClass] alloc] init];
// Dynamic Dispatch
[object dynamicMethod];
// Direct Dispatch
[object directMethod];
性能评价
对于程序开发来讲,“直接”自然比“间接”效率更高,那么direct method
是否会真的对性能有很大增益呢?文章观点却是:
In most cases, making a method direct probably won’t have a noticeable performance advantage.
在绝大多数情况,“让方法直接”可能不会有显著的性能优势。
因为事实证明,objc_msgSend
已经是十分地快。这也得益其缓存策略、底层优化、现代中央处理器固有的运行特性。个人认为前二者分别指的是:快速查找流程、其方法基于更靠近底层的汇编语言实现(详细的可看开源代码的objc-msg-arm64.s),第三者应该是硬件相关,有知道的同学欢迎补充。
原文在说明这点时还引用了自己的另一篇文章的链接,引文中,iPhone 6s在iOS 9.3.1上“Objective-C message send”运行1000000000(9个0)次共花了2.7s,如果是“IMP-cached message send”同样次数自然是更短:1.2s,而“C++ virtual method call”运行了同样次数也不过0.8s,这也摆明告诉我们:代码慢仅仅是因为代码烂而已(doge)。
隐藏可见性
一个direct method
,它的implementation
会拥有隐藏可见性,也就是说,direct methods
仅仅可以相同的module
(文中还提到了个考究的说法,linkage unit)调用,他不会暴露在OC的runtime当中。
如果需要在代码上测验的同学可以用下面这段代码:
MyClass *meClass = [[MyClass alloc]init];
BOOL respondToDynamicMethod = [meClass respondsToSelector:@selector(dynamicMethod)];
//以下两行报错:@selector expression formed with direct selector 'directMethod'
BOOL respondToDirectMethod = [meClass respondsToSelector:@selector(directMethod)];
[meClass performSelector:@selector(directMethod)];
隐藏可见性会带来两个直接的好处:
- 更小的二进制大小
- 没有外部调用
部分英语单词的含义
dispatch 分派/分发
Object-Oriented Programming(OOP) 面向对象编程
invoke 调用
maintain 维持
consult 查阅
inheritance chain 继承链
deem 认为,视为
shebang 事情,工作
underlying implementation 底层实现
annotate 注释,作注解
property declarations 属性声明
implicit methods 隐式方法
property 和 synthesize
详细参考链接
《Objective-C Direct Methods》学习笔记的更多相关文章
- js学习笔记:webpack基础入门(一)
之前听说过webpack,今天想正式的接触一下,先跟着webpack的官方用户指南走: 在这里有: 如何安装webpack 如何使用webpack 如何使用loader 如何使用webpack的开发者 ...
- PHP-自定义模板-学习笔记
1. 开始 这几天,看了李炎恢老师的<PHP第二季度视频>中的“章节7:创建TPL自定义模板”,做一个学习笔记,通过绘制架构图.UML类图和思维导图,来对加深理解. 2. 整体架构图 ...
- PHP-会员登录与注册例子解析-学习笔记
1.开始 最近开始学习李炎恢老师的<PHP第二季度视频>中的“章节5:使用OOP注册会员”,做一个学习笔记,通过绘制基本页面流程和UML类图,来对加深理解. 2.基本页面流程 3.通过UM ...
- 2014年暑假c#学习笔记目录
2014年暑假c#学习笔记 一.C#编程基础 1. c#编程基础之枚举 2. c#编程基础之函数可变参数 3. c#编程基础之字符串基础 4. c#编程基础之字符串函数 5.c#编程基础之ref.ou ...
- JAVA GUI编程学习笔记目录
2014年暑假JAVA GUI编程学习笔记目录 1.JAVA之GUI编程概述 2.JAVA之GUI编程布局 3.JAVA之GUI编程Frame窗口 4.JAVA之GUI编程事件监听机制 5.JAVA之 ...
- seaJs学习笔记2 – seaJs组建库的使用
原文地址:seaJs学习笔记2 – seaJs组建库的使用 我觉得学习新东西并不是会使用它就够了的,会使用仅仅代表你看懂了,理解了,二不代表你深入了,彻悟了它的精髓. 所以不断的学习将是源源不断. 最 ...
- CSS学习笔记
CSS学习笔记 2016年12月15日整理 CSS基础 Chapter1 在console输入escape("宋体") ENTER 就会出现unicode编码 显示"%u ...
- HTML学习笔记
HTML学习笔记 2016年12月15日整理 Chapter1 URL(scheme://host.domain:port/path/filename) scheme: 定义因特网服务的类型,常见的为 ...
- DirectX Graphics Infrastructure(DXGI):最佳范例 学习笔记
今天要学习的这篇文章写的算是比较早的了,大概在DX11时代就写好了,当时龙书11版看得很潦草,并没有注意这篇文章,现在看12,觉得是跳不过去的一篇文章,地址如下: https://msdn.micro ...
- ucos实时操作系统学习笔记——任务间通信(消息)
ucos另一种任务间通信的机制是消息(mbox),个人感觉是它是queue中只有一个信息的特殊情况,从代码中可以很清楚的看到,因为之前有关于queue的学习笔记,所以一并讲一下mbox.为什么有了qu ...
随机推荐
- [FAQ] FinalCutPro 视频背景加模糊效果
1. 时间轴右上方,找到 倒数第二个 "显示或隐藏效果浏览器",里面有一个 "模糊" 效果: 2. "模糊"效果中的 "高斯曲线& ...
- [Gin] 单文件极简 HTTP Server 流程分析 ( gin-gonic/gin )
/** * example.go * * @link https://cnblogs.com/farwish */package main import "github.com/gin-go ...
- dotnet SemanticKernel 入门 注入日志
使用 SemanticKernel 框架在对接 AI 时,由于使用到了大量的魔法,需要有日志的帮助才好更方便定位问题,本文将告诉大家如何在 SemanticKernel 注入日志 本文属于 Seman ...
- Oracle和达梦:相似度函数:UTL_MATCH
UTL_MATCH介绍: Oracle的UTL_MATCH包是一个提供字符串匹配和相似度计算功能的工具包.它包含了一系列函数,用于执行字符串比较.相似度计算和模式匹配等操作. UTL_MATCH包中的 ...
- 四、【转】基于知识图谱的推荐系统(KGRS)综述
以下文章来源于AI自然语言处理与知识图谱 ,作者Elesdspline 导语 本文是2020年针对知识图谱作为辅助信息用于推荐系统的一篇综述.知识图谱对于推荐系统不仅能够进行更精确的个性化推荐,而且对 ...
- linux定时任务crontab 周期执行任务
目录 1. crontab主要作用 2. 如何添加crontab 定时任务 3. 计划任务,crontab命令选项: 4. cron文件语法: 5. 查看计划任务 1 创建脚本文件test.py,在文 ...
- 关于sql server导出csv格式文件的身份证号乱码问题处理办法
1.使用SQL Server数据库经常会遇到导出大量数据的情况,例如导出40万条数据,虽然EXCL支持可以放入百万的数据,但是使用数据库复制,粘贴到EXCL表格时,数据库会提示溢出的情况,如下图所示: ...
- 用 C 语言开发一门编程语言 — S-表达式
目录 文章目录 目录 前文列表 使用 S-表达式进行重构 读取并存储输入 实现 S-Expression 语法解析器 实现 S-Expression 存储器 实现 lval 变量的构造函数 实现 lv ...
- java学习之旅(day.01)
Markdown学习 标题 一级标题:#空格+标题名字 二级标题:##空格+标题名字 三级标题:###空格+标题名字 字体 粗体:两边都加两个** Hello,world 斜体:两边都加一个* Hel ...
- windows下使用winget快速安装nvm
前置条件: 操作系统 >= win10 安装 首先使用winget搜索nvm包 winget search nvm #搜索结果如下图 安装nvm winget install CoreyButl ...