美文网首页iOS
iOS-isa指向图&类结构(上)

iOS-isa指向图&类结构(上)

作者: Summit_yp | 来源:发表于2021-06-19 23:34 被阅读0次

一.isa & superclass的指向探究

靓仔们,我们在main.m中添加如下代码:

@interface YPPerson : NSObject
@end

@implementation YPPerson
@end

@interface YPTeacher : YPPerson
@end

@implementation YPTeacher
@end

iOS-对象的本质,ISA分析中提到了clang,这里我们仍然使用clang -rewrite-objc main.m -o main.cpp编译main.m文件,打开main.cpp,搜索YPPerson,得到如下结果:

static void OBJC_CLASS_SETUP_$_YPPerson(void ) {
    //YPPerson的元类的isa指向NSObject的元类,也就是根元类
    OBJC_METACLASS_$_YPPerson.isa = &OBJC_METACLASS_$_NSObject;
    //YPPerson的元类的父类指向NSObject的元类,也就是根元类
    OBJC_METACLASS_$_YPPerson.superclass = &OBJC_METACLASS_$_NSObject;
    OBJC_METACLASS_$_YPPerson.cache = &_objc_empty_cache;
    //YPPerson类对象的isa指向YPPerson的元类
    OBJC_CLASS_$_YPPerson.isa = &OBJC_METACLASS_$_YPPerson;
    //YPPerson类对象的父类指向NSObject的类对象
    OBJC_CLASS_$_YPPerson.superclass = &OBJC_CLASS_$_NSObject;
    OBJC_CLASS_$_YPPerson.cache = &_objc_empty_cache;
}

搜索YPTeacher,得到如下关键信息:

static void OBJC_CLASS_SETUP_$_YPTeacher(void ) {
    //YPTeacher的元类的isa指向NSObject的元类,也就是根元类
    OBJC_METACLASS_$_YPTeacher.isa = &OBJC_METACLASS_$_NSObject;
    //YPTeacher的元类的父类指向YPPerson的元类
    OBJC_METACLASS_$_YPTeacher.superclass = &OBJC_METACLASS_$_YPPerson;
    OBJC_METACLASS_$_YPTeacher.cache = &_objc_empty_cache;
    //YPTeacher类对象的isa指向YPTeacher的元类
    OBJC_CLASS_$_YPTeacher.isa = &OBJC_METACLASS_$_YPTeacher;
    //YPTeacher类对象的父类指向YPPerson的类对象
    OBJC_CLASS_$_YPTeacher.superclass = &OBJC_CLASS_$_YPPerson;
    OBJC_CLASS_$_YPTeacher.cache = &_objc_empty_cache;
}

oh my gad! 这也太直观了吧,接下来有请我们著名的isa走向图,将其与我们的例子相结合:


isa & superclass 的指向图

相信这个时候来看就清晰了许多,那么怎么验证图中实例对象isa的走向呢?

main.m中添加如下代码:

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        YPPerson *instancePerson = [YPPerson alloc];
        YPTeacher *instanceTeacher = [YPTeacher alloc];
        NSLog(@"%@,%@",instancePerson,instanceTeacher);
    }
    return 0;
}

打下断点并运行:

image.png
使用lldb调试:
image.png
拿到isa&ISA_MASK就得到isa的真实指向,即YPPerson
image.png
同理得到YPTeacher

类的结构的探究

已知类在底层是object_class的结构体,直接在源码中搜索object_class,关键源码如下:

image.png

可以知道,类中有以下变量:

    // Class ISA;
    Class superclass;
    cache_t cache;             // formerly cache pointer and vtable
    class_data_bits_t bits;    // class_rw_t * plus custom rr/alloc flags

为什么ISA被注释掉了呢?因为这个是由objc_object继承而来

image.png

其每个变量的大小如下,ISAsuperclass都是结构体指针为8字节,cache的大小为16字节

    // Class ISA;                   // 8字节
    Class superclass;         // 8字节
    cache_t cache;             // 16字节
    class_data_bits_t bits;    

那么类的相关信息例如属性,方法列表都存在那里呢?

直接开启上帝视角,答案是存在 bits中,我们来看看bit的结构吧。

class_data_bits_t结构
直接定位到data()方法,看看class_rw_t中都有些什么呢?
class_rw_t结构
诶嘿,找到methods() properties() protocols()啦。接下来我们用lldb调试,验证一下吧。

YPPerson添加一些属性,方法

@interface YPPerson : NSObject
{
    NSString *name;
}
@property (copy,nonatomic)NSString *yp_name;
- (void)handsomYP;
+ (void)beautifulWife;

@end

打上断点,运行源码。


image.png image.png image.png

属性同理,一步步走进去就可以看见啦。那么问题来了,- (void)handsomYP帅气我们有了,+ (void)beautifulWife这个漂亮老婆跑哪去了呢?

(lldb) x/4gx YPPerson.class
0x1000087c0: 0x0000000100008798 0x0000000100357140
0x1000087d0: 0x0000000100352360 0x0000802000000000
(lldb) p/x 0x0000000100008798 & 0x00007ffffffffff8ULL//isa&isa_mask
(unsigned long long) $16 = 0x0000000100008798//元类的地址
(lldb) po 0x0000000100008798 & 0x00007ffffffffff8ULL
YPPerson//元类
//后续就跟上一步获取方法列表一样啦
(lldb) x/4gx 0x0000000100008798
0x100008798: 0x00000001003570f0 0x00000001003570f0
0x1000087a8: 0x00000001019048d0 0x0002e03100000003
(lldb) p (class_data_bits_t *)0x1000087b8
(class_data_bits_t *) $18 = 0x00000001000087b8
(lldb) p $18->data()
(class_rw_t *) $19 = 0x0000000100774810
(lldb) p *$19
(class_rw_t) $20 = {
  flags = 2684878849
  witness = 1
  ro_or_rw_ext = {
    std::__1::atomic<unsigned long> = {
      Value = 4302785969
    }
  }
  firstSubclass = nil
  nextSiblingClass = 0x00007fff90831cd8
}
(lldb) p $20.methods()
(const method_array_t) $21 = {
  list_array_tt<method_t, method_list_t, method_list_t_authed_ptr> = {
     = {
      list = {
        ptr = 0x0000000100008080
      }
      arrayAndFlag = 4295000192
    }
  }
}
(lldb) p $21.list
(const method_list_t_authed_ptr<method_list_t>) $22 = {
  ptr = 0x0000000100008080
}
(lldb) p $22.ptr
(method_list_t *const) $23 = 0x0000000100008080
(lldb) p *$23
(method_list_t) $24 = {
  entsize_list_tt<method_t, method_list_t, 4294901763, method_t::pointer_modifier> = (entsizeAndFlags = 27, count = 1)
}
(lldb) p $24.get(0).big()
(method_t::big) $25 = {
  name = "beautifulWife"
  types = 0x0000000100003e24 "v16@0:8"
  imp = 0x0000000100003810 (KCObjcBuild`+[YPPerson beautifulWife] at main.m:51)
}

由此可知,beautifulWife在元类的方法列表里去啦,终于找到漂亮老婆了,嘿嘿。

看我帖子的都能找到beautifulWife,😁😁😁

相关文章

  • iOS-类结构(中)

    类结构 hxdm,在iOS-isa指向图&类结构[https://www.jianshu.com/p/782ccf...

  • iOS-isa指向图&类结构(上)

    一.isa & superclass的指向探究 靓仔们,我们在main.m中添加如下代码: 在iOS-对象的本质,...

  • iOS-类结构(下)

    在iOS-isa指向图&类结构[https://www.jianshu.com/p/782ccfc77f1c]中提...

  • isa指针指向和类结构分析

    isa指针指向和类结构分析 isa指向图 经典的isa指向图 从这张图能总结出类继承自父类,父类继承于NSObje...

  • ISA指向、类结构

    ISA指向、类结构 1.ISA指向 上次在对象本质和ISA指针[https://www.jianshu.com/p...

  • 指针初步了解

    结构体和类 本质区别: 类的本质是结构体,但是指针指向一个类 和指向一个结构体是不同的概念 例证: nsstrin...

  • Android Framework 添加新的 系统服务

    基于 上一篇 对 AMS 的类图结构的学习,AMS 类图结构[https://www.jianshu.com/p/...

  • OC底层原理06 - 类结构探索(1)

    类是什么? 类:指向objc_class结构体的指针 对象:指向objc_object结构体的指针 从上面源码中可...

  • C++ 指向类的指针

    原文地址:C++ 指向类的指针 一个指向 C++ 类的指针与指向结构的指针类似,访问指向类的指针的成员,需要使用成...

  • 元类(Meta Class)

    struct objc_object结构体实例它的isa指针指向类对象,类对象的isa指针指向了元类,super_...

网友评论

    本文标题:iOS-isa指向图&类结构(上)

    本文链接:https://www.haomeiwen.com/subject/ruokyltx.html