加入收藏 | 设为首页 | 会员中心 | 我要投稿 东莞站长网 (https://www.0769zz.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 站长资讯 > 评论 > 正文

Swift 5.0的Runtime机制浅析

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

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

extension中定义的方法

(编辑:东莞站长网)

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

热点阅读