runtime的理解

2017-04-08  本文已影响16人  43b86d3b5040

runtime是oc的一种代码运行机制,我们程序中执行的代码最终都会以c语言的形式执行,例如:[target doSomething] 在运行中会被转换成 objc_msgSend(target,@selector(doSomething));
对象在runtime中都以结构体的形式体现

struct objc_class {
    Class isa;//指针,顾名思义,表示是一个什么,
    //实例的isa指向类对象,类对象的isa指向元类
    
#if !__OBJC2__
    Class super_class;  //指向父类
    const char *name;  //类名
    long version;
    long info;
    long instance_size
    struct objc_ivar_list *ivars //成员变量列表
    struct objc_method_list **methodLists; //方法列表
    struct objc_cache *cache;//缓存
    //一种优化,调用过的方法存入缓存列表,下次调用先找缓存
    struct objc_protocol_list *protocols //协议列表
#endif
} OBJC2_UNAVAILABLE;

下面我们通过oc中方法的调用来了解一下runtime的过程

如果用实例对象调用实例方法,会到实例的isa指针指向的对象(也就是类对象)操作
如果调用的是类方法,就会到类对象的isa指针指向的对象(也就是元类对象)中操作

  1. 首先,在相应操作的对象中的缓存方法列表中找打调用的方法,如果找到,转向相应的实现并执行。
  2. 如果没找到,在相应操作的对象中的方法列表中找调用的方法,如果找到,转向相应实现并执行。
  3. 如果没找到,去父类指针所指向的对象中执行1 2
  4. 以此类推,如果一直到根类还没找到,转向拦截调用。
  5. 如果没有重写拦截调用方法,程序报错。

也就是说如果继承重写父类的方法,并不会将父类方法覆盖,只是在当前子类找到了该方法,不再继续找了。

用runtime可以做什么?
一般的开发中用不到,只有一些特殊场景,比如通过objc_setAssociatedObject扩展对象的属性,而又不使用继承方案,或使用method_exchangeImplementations来执行自己的方法,而不执行系统类的方法。

基本参考这里;

上一篇下一篇

猜你喜欢

热点阅读