原文通过对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》学习笔记的更多相关文章

  1. js学习笔记:webpack基础入门(一)

    之前听说过webpack,今天想正式的接触一下,先跟着webpack的官方用户指南走: 在这里有: 如何安装webpack 如何使用webpack 如何使用loader 如何使用webpack的开发者 ...

  2. PHP-自定义模板-学习笔记

    1.  开始 这几天,看了李炎恢老师的<PHP第二季度视频>中的“章节7:创建TPL自定义模板”,做一个学习笔记,通过绘制架构图.UML类图和思维导图,来对加深理解. 2.  整体架构图 ...

  3. PHP-会员登录与注册例子解析-学习笔记

    1.开始 最近开始学习李炎恢老师的<PHP第二季度视频>中的“章节5:使用OOP注册会员”,做一个学习笔记,通过绘制基本页面流程和UML类图,来对加深理解. 2.基本页面流程 3.通过UM ...

  4. 2014年暑假c#学习笔记目录

    2014年暑假c#学习笔记 一.C#编程基础 1. c#编程基础之枚举 2. c#编程基础之函数可变参数 3. c#编程基础之字符串基础 4. c#编程基础之字符串函数 5.c#编程基础之ref.ou ...

  5. JAVA GUI编程学习笔记目录

    2014年暑假JAVA GUI编程学习笔记目录 1.JAVA之GUI编程概述 2.JAVA之GUI编程布局 3.JAVA之GUI编程Frame窗口 4.JAVA之GUI编程事件监听机制 5.JAVA之 ...

  6. seaJs学习笔记2 – seaJs组建库的使用

    原文地址:seaJs学习笔记2 – seaJs组建库的使用 我觉得学习新东西并不是会使用它就够了的,会使用仅仅代表你看懂了,理解了,二不代表你深入了,彻悟了它的精髓. 所以不断的学习将是源源不断. 最 ...

  7. CSS学习笔记

    CSS学习笔记 2016年12月15日整理 CSS基础 Chapter1 在console输入escape("宋体") ENTER 就会出现unicode编码 显示"%u ...

  8. HTML学习笔记

    HTML学习笔记 2016年12月15日整理 Chapter1 URL(scheme://host.domain:port/path/filename) scheme: 定义因特网服务的类型,常见的为 ...

  9. DirectX Graphics Infrastructure(DXGI):最佳范例 学习笔记

    今天要学习的这篇文章写的算是比较早的了,大概在DX11时代就写好了,当时龙书11版看得很潦草,并没有注意这篇文章,现在看12,觉得是跳不过去的一篇文章,地址如下: https://msdn.micro ...

  10. ucos实时操作系统学习笔记——任务间通信(消息)

    ucos另一种任务间通信的机制是消息(mbox),个人感觉是它是queue中只有一个信息的特殊情况,从代码中可以很清楚的看到,因为之前有关于queue的学习笔记,所以一并讲一下mbox.为什么有了qu ...

随机推荐

  1. 什么是IPD项目管理模式?聊聊IPD下的产品研发流程

    IPD(集成产品开发)涵盖了产品从创意提出到研发.生产.运营等,包含了产品开发到营销运营的整个过程.围绕产品(或项目)生命周期的过程的管理模式,是一套生产流程,更是时下国际先进的管理体系.IPD(集成 ...

  2. 自动生成robot自动化测试用例

    背景:java项目使用swagger管理接口,随着需求的开发接口也有增加,要从swagger界面中去查找出新增的接口是件很费时,效率很低的事情. 适用情况: java项目且适用swagger管理接口 ...

  3. Ubuntu 安装谷歌中文输入法

    Ubuntu 安装谷歌中文输入法 下载谷歌拼音:sudo apt-get install fcitx-googlepinyin 点击设置: 第一次打开需要点击安装: 设置完成后重启系统 点击右上角键盘 ...

  4. Ubuntu的apt-get/yarm/wget命令详解

    目录 一.查看本机是否安装软件 二.apt-get 三.yum 四.wget apt-cache和apt-get是apt包的管理工具, 他们根据/etc/apt/sources.list里的软件源地址 ...

  5. HDU 多校 2023 Round #5 题解

    HDU 多校 2023 Round #5 题解 \(\text{By DaiRuiChen007}\) A. Typhoon Problem Link 题目大意 给一条 \(n\) 个点构成的折线,\ ...

  6. ContextCapture中的模型航拍方法和技巧

    在进行实景建模之前,获取被拍摄物体的照片是很重要的一项工作,因为如果没有按照规则拍摄或者拍摄相片质量不佳,将会直接影响我们后期建模,甚至无法建模. 我们建议使用ContextCapture进行建模,则 ...

  7. flex布局方案

    参考:https://blog.csdn.net/weixin_39717076/article/details/82586915

  8. 微信小程序长按识别二维码

    微信小程序长按识别二维码 image 组件中二维码/小程序码图片不支持长按识别.仅在 wx.previewImage 中支持长按识别示例代码

  9. Android 13 - Media框架(2)- Demo App与MediaPlayer Api了解

    关注公众号免费阅读全文,进入音视频开发技术分享群! 尝试用MediaPlayer写了一个播放demo,实现了网络流和本地流的播放.由于本人对app开发一窍不通,所以demo中很多内容是边查资料边写的, ...

  10. k8s ingress部署安装

    ingress概念 ingress与service,deployment同样都是k8s中的一种资源 ingress用于实现域名方式访问k8s内部应用 安装ingress 1. 安装helm: wget ...