评论

收藏

[iOS开发] 《Objective-C Direct Methods》学习笔记

移动开发 移动开发 发布于:2022-03-13 15:36 | 阅读数:343 | 评论:0

原文通过对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 synthesis
本文来自博客园,作者:MrYu4,转载请注明原文链接:https://www.cnblogs.com/MrYU4/p/objectivec-direct-methods-xue-xi-bi-ji.html


   
   
   
                        

关注下面的标签,发现更多相似文章