加入收藏 | 设为首页 | 会员中心 | 我要投稿 安阳站长网 (https://www.0372zz.cn/)- 高性能计算、分布式云、混合云存储、云计算、视频终端!
当前位置: 首页 > 站长资讯 > 评论 > 正文

Swift 5.0的Runtime机制浅析

发布时间:2019-07-19 05:20:55 所属栏目:评论 来源:欧阳大哥2013
导读:导读:你想知道Swift内部对象是如何创建的吗?方法以及函数调用又是如何实现的吗?成员变量的访问以及对象内存布局又是怎样的吗?这些问题都会在这篇文章中得到解答。为了更好的让大家理解这些内部实现,我会将源代码翻译为用C语言表示的伪代码来实现。 Objec

如果在Swift中的使用了OC类,比如还在使用的UIViewController、UIView等等。并且还重写了基类的方法,比如一定会重写UIViewController的viewDidLoad方法。对于这些类的重写的方法定义信息还是会保存在类的Class结构体中,而在调用上还是采用OC语言的Runtime机制来实现,即通过objc_msgSend来调用。而如果在OC派生类中定义了一个新的方法的话则实现和调用机制就不会再采用OC的Runtime机制来完成了,比如说在UIView的派生类中定义了一个新方法foo,那么这个新方法的调用和实现将与OC的Runtime机制没有任何关系了! 它的处理和实现机制会变成我下面要说到的第三种方式。下面的Swift源代码以及C伪代码实现说明了这个情况:

  1. ////////Swift源代码 
  2.  
  3. //类定义 
  4. class MyUIView:UIView { 
  5.     open func foo(){}   //常规方法 
  6.     override func layoutSubviews() {}  //重写OC方法 
  7. } 
  8.  
  9. func main(){ 
  10.   let obj = MyUIView() 
  11.   obj.layoutSubviews()   //调用OC类重写的方法 
  12.   obj.foo()   //调用常规的方法。 
  13. } 
  14.  
  15. ////////C伪代码 
  16.  
  17. //...........................................运行时定义部分 
  18.  
  19. //OC类的方法结构体 
  20. struct method_t { 
  21.     SEL name; 
  22.     IMP imp; 
  23. }; 
  24.  
  25. //Swift类描述 
  26. struct swift_class { 
  27.     ...   //其他的属性,因为这里不关心就不列出了。 
  28.     struct method_t  methods[1]; 
  29.     ...   //其他的属性,因为这里不关心就不列出了。 
  30.     //虚函数表刚好在结构体的第0x50的偏移位置。 
  31.     IMP vtable[1]; 
  32. }; 
  33.  
  34.  
  35. //...........................................源代码中类的定义和方法的定义和实现部分 
  36.  
  37. //类定义 
  38. struct MyUIView { 
  39.       struct swift_class *isa; 
  40. } 
  41.  
  42. //类的方法函数的实现 
  43. void layoutSubviews(id self, SEL _cmd){} 
  44. void foo(){}  //Swift类的常规方法中和源代码的参数保持一致。 
  45.  
  46. //类的描述信息构建,这些都是在编译代码时就明确了并且保存在数据段中。 
  47. struct swift_class classMyUIView; 
  48. classMyUIView.methods[0] = {"layoutSubviews", &layoutSubviews}; 
  49. classMyUIView.vtable[0] = {&foo}; 
  50.  
  51.  
  52. //...........................................源代码中程序运行的部分 
  53.  
  54. void main(){ 
  55.   MyUIView *obj = MyUIView.__allocating_init(classMyUIView); 
  56.   obj->isa = &classMyUIView; 
  57.   //OC类重写的方法layoutSubviews调用还是用objc_msgSend来实现 
  58.   objc_msgSend(obj, @selector(layoutSubviews); 
  59.   //Swift方法调用时对象参数被放到x20寄存器中 
  60.   asm("mov x20, obj"); 
  61.   //Swift的方法foo调用采用间接调用实现 
  62.   obj->isa->vtable[0](); 
  63. } 

extension中定义的方法

(编辑:安阳站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

推荐文章
    热点阅读