美文网首页
类的结构初探

类的结构初探

作者: 辣比小新 | 来源:发表于2019-12-23 15:36 被阅读0次

    本篇文章针对类的结构进行初步的分析,对之前学习的内容做一个小小的总结。

    文章的分析主要是利用lldb断点调试,通过查看类的内存空间,分析定位类的实例变量、属性、对象方法和类方法在编译之后的存储位置。

    1、首先在main方法中添加代码,并且在NSLog那一行打上断点:

    、、、

    int main(int argc,const char* argv[]) {

        @autoreleasepool {

            LGPerson*person = [LGPerson alloc];

            Class pClass   =object_getClass(person);

            NSLog(@"%@ - %p",person,pClass);

        }

        return0;

    }

    、、、

    2、然后通过命令查看pClass的内存地址:

    、、、

     x/4gx pClass

    0x1000023b0: 0x001d800100002389 0x0000000100afe140

    0x1000023c0: 0x00000001003a1270 0x0000000000000000

    、、、

    通过分析objc_class结构体的定义:

    、、、

    struct objc_class : objc_object {

        // Class ISA; // 8,继承自父类

        Class superclass; // 8

        cache_t cache;    // 16 不是8        // formerly cache pointer and vtable

        class_data_bits_t bits;    // class_rw_t * plus custom rr/alloc flags

        class_rw_t*data() { 

            returnbits.data();

        }

    ......

    }

    、、、

    可以定位到bits的内存初始位置:0x1000023b0 + 20(偏移量)= 0x1000023d0

    3、输入命令:

    、、、

    p (class_data_bits_t *)0x1000023d0

    (class_data_bits_t *) $1 = 0x00000001000023d0

    p $1->data()

    (class_rw_t *) $2 = 0x0000000100f90810

    p *$2

    (class_rw_t) $3 = {

      flags = 2148139008

      version = 0

      ro = 0x0000000100002308

      methods = {

        list_array_tt = {

           = {

            list = 0x0000000100002240

            arrayAndFlag = 4294976064

          }

        }

      }

      properties = {

        list_array_tt = {

           = {

            list = 0x00000001000022f0

            arrayAndFlag = 4294976240

          }

        }

      }

      protocols = {

        list_array_tt = {

           = {

            list = 0x0000000000000000

            arrayAndFlag = 0

          }

        }

      }

      firstSubclass = nil

      nextSiblingClass = NSDate

      demangledName = 0x0000000000000000

    }

    、、、

    4.猜测:有关属性、方法和协议的相关信息分别存在$3的properties、methods和protocols中,但是通过p(po)命令查看,猜测错误。它们真正的位置在$3的ro里面,下面去一一验证。

    5.验证

    、、、

    (lldb) p *$3.ro

    (const class_ro_t) $5 = {

      flags = 388

      instanceStart = 8

      instanceSize = 24

      reserved = 0

      ivarLayout = 0x0000000100001f89 "\x02"

      name = 0x0000000100001f80 "LGPerson"

      baseMethodList = 0x0000000100002240

      baseProtocols = 0x0000000000000000

      ivars = 0x00000001000022a8

      weakIvarLayout = 0x0000000000000000

      baseProperties = 0x00000001000022f0

    }

    p *$5.baseProperties

    (property_list_t) $6 = {

      entsize_list_tt = {

        entsizeAndFlags = 16

        count = 1

        first = (name = "nickName", attributes = "T@\"NSString\",C,N,V_nickName")

      }

    }

    p *$5.baseMethodList

    (method_list_t) $7 = {

      entsize_list_tt = {

        entsizeAndFlags = 26

        count = 4

        first = {

          name = "sayHello"

          types = 0x0000000100001f8b "v16@0:8"

          imp = 0x0000000100001b90 (LGTest`-[LGPerson sayHello] at LGPerson.m:13)

        }

      }

    }

    p *$5.ivars

    (const ivar_list_t) $8 = {

      entsize_list_tt = {

        entsizeAndFlags = 32

        count = 2

        first = {

          offset = 0x0000000100002378

          name = 0x0000000100001e64 "hobby"

          type = 0x0000000100001fa6 "@\"NSString\""

          alignment_raw = 3

          size = 8

        }

      }

    }

    、、、

    但是,类方法并没有保存在 baseMethodList里面,而是保存在元类里面。

    但是,类方法并没有保存在 baseMethodList里面,而是保存在元类里面。

    但是,类方法并没有保存在 baseMethodList里面,而是保存在元类里面。

    相关文章

      网友评论

          本文标题:类的结构初探

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