加入收藏 | 设为首页 | 会员中心 | 我要投稿 PHP编程网 - 金华站长网 (https://www.0579zz.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 业界 > 正文

Swift 5.0的Runtime机制浅析

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

如果是在Swift中定义的常规方法,方法的调用机制和C++中的虚函数的调用机制是非常相似的。Swift为每个类都建立了一个被称之为虚表的数组结构,这个数组会保存着类中所有定义的常规成员方法函数的地址。每个Swift类对象实例的内存布局中的第一个数据成员和OC对象相似,保存有一个类似isa的数据成员。isa中保存着Swift类的描述信息。对于Swift类的类描述结构苹果并未公开(也许有我并不知道),类的虚函数表保存在类描述结构的第0x50个字节的偏移处,每个虚表条目中保存着一个常规方法的函数地址指针。每一个对象方法调用的源代码在编译时就会转化为从虚表中取对应偏移位置的函数地址来实现间接的函数调用。下面是对于常规方法的调用Swift语言源代码和C语言伪代码实现:

  1. ////////Swift源代码 
  2.  
  3. //基类定义 
  4. class CA { 
  5.   open func foo1(_ a:Int){} 
  6.   open func foo1(_ a:Int, _ b:Int){} 
  7.   open func foo2(){} 
  8.  
  9. //扩展 
  10. extension CA{ 
  11.   open func extfoo(){}  
  12.  
  13. //派生类定义 
  14. class CB:CA{ 
  15.   open func foo3(){} 
  16.   override open func foo1(_ a:Int){} 
  17.  
  18. func testfunc(_ obj:CA){ 
  19.   obj.foo1(10) 
  20.  
  21. func main() { 
  22.   let objA = A() 
  23.   objA.foo1(10) 
  24.   objA.foo1(10,20) 
  25.   objA.foo2() 
  26.   objA.extfoo() 
  27.  
  28.   let objB = B() 
  29.   objB.foo1(10) 
  30.   objB.foo1(10,20) 
  31.   objB.foo2() 
  32.   objB.foo3() 
  33.   objB.extfoo() 
  34.  
  35.   testfunc(objA) 
  36.   testfunc(objB) 
  37.  
  38. ////////C伪代码 
  39.  
  40. //...........................................运行时定义部分 
  41.  
  42. //Swift类描述。 
  43. struct swift_class { 
  44.     ...   //其他的属性,因为这里不关心就不列出了 
  45.     //虚函数表刚好在结构体的第0x50的偏移位置。 
  46.     IMP vtable[0]; 
  47. }; 
  48.  
  49.  
  50. //...........................................源代码中类的定义和方法的定义和实现部分 
  51.  
  52.  
  53. //基类定义 
  54. struct CA { 
  55.       struct swift_class *isa; 
  56. }; 
  57.  
  58. //派生类定义 
  59. struct CB { 
  60.    struct swift_class *isa; 
  61. }; 
  62.  
  63. //基类CA的方法函数的实现,这里对所有方法名都进行修饰命名 
  64. void _$s3XXX2CAC4foo1yySiF(int a){}   //CA类中的foo1 
  65. void _$s3XXX2CAC4foo1yySi_SitF(int a, int b){} //CA类中的两个参数的foo1 
  66. void _$s3XXX2CAC4foo2yyF(){}   //CA类中的foo2 
  67. void _$s3XXX2CAC6extfooyyF(){} //CA类中的extfoo函数   
  68.  
  69. //派生类CB的方法函数的实现。 
  70. void _$s3XXX2CBC4foo1yySiF(int a){}   //CB类中的foo1,重写了基类的方法,但是名字不一样了。 
  71. void _$s3XXX2CBC4foo3yyF(){}             //CB类中的foo3 
  72.  
  73.  //构造基类的描述信息以及虚函数表 
  74. struct swift_class classCA; 
  75. classCA.vtable[3] = {&_$s3XXX2CAC4foo1yySiF, &_$s3XXX2CAC4foo1yySi_SitF, &_$s3XXX2CAC4foo2yyF}; 
  76.  
  77. //构造派生类的描述信息以及虚函数表,注意这里虚函数表会将基类的函数也添加进来而且排列在前面。 
  78. struct swift_class classCB; 
  79. classCB.vtable[4] = {&_$s3XXX2CBC4foo1yySiF, &_$s3XXX2CAC4foo1yySi_SitF, &_$s3XXX2CAC4foo2yyF, &_$s3XXX2CBC4foo3yyF}; 
  80.  
  81. void testfunc(A *obj){ 
  82.    obj->isa->vtable[0](10);   //间接调用实现多态的能力。 
  83.  
  84.  
  85. //...........................................源代码中程序运行的部分 
  86.  
  87. void main(){ 
  88.    CA *objA = CA.__allocating_init(classCA); 
  89.    objA->isa = &classCA; 
  90.    asm("mov x20, objA") 
  91.    objA->isa->vtable[0](10); 
  92.    objA->isa->vtable[1](10,20); 
  93.    objA->isa->vtable[2](); 
  94.    _$s3XXX2CAC6extfooyyF() 
  95.  
  96.   CB *objB = CB.__allocating_init(classCB); 
  97.   objB->isa = &classCB; 
  98.   asm("mov x20, objB"); 
  99.   objB->isa->vtable[0](10); 
  100.   objB->isa->vtable[1](10,20); 
  101.   objB->isa->vtable[2](); 
  102.   objB->isa->vtable[3](); 
  103.    _$s3XXX2CAC6extfooyyF(); 
  104.  
  105.   testfunc(objA); 
  106.   testfunc(objB); 
  107.  

从上面的代码中可以看出一些特点:

(编辑:PHP编程网 - 金华站长网)

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