美文网首页
类的结构分析

类的结构分析

作者: 竹屋听雨 | 来源:发表于2019-12-24 16:01 被阅读0次

    指针

    ###普通指针:
    int a = 10;// 在内存里有一个10;我们定义一个变量a ,把 10 赋值给变量a; 这个过程叫值拷贝;
    int b = 10; //
    LGNSLog(@"%d -- %p",a,&a);
    LGNSLog(@"%d -- %p",b,&b);
    打印结果:值是一样的,但是a,b 在内存里的地址是不一样哦。
    10 -- 0x7ffeefbff4ac
    10 -- 0x7ffeefbff4a8
    Mark:&a  --> int a = 10;
    
    ###对象:指针拷贝 
    实例化出来两个对象,这两个对象分别又被两个不同的指针指向着。
      LGPerson *p1 = [LGPerson alloc];
      LGPerson *p2 = [LGPerson alloc];       
    LGNSLog(@"%@ -- %p",p1,&p1);        
    LGNSLog(@"%@ -- %p",p2,&p2);
    打印结果:
    <LGPerson: 0x100693610> -- 0x7ffeefbff4a0
    <LGPerson: 0x1006929f0> -- 0x7ffeefbff498
    Mark:&p1 --->p1 ---> LGPerson
    
    
    ### 数组指针
    int c[4] = {1,2,3,4};
    int *d   = c;
    NSLog(@"%p - %p - %p",&c,&c[0],&c[1]);
    NSLog(@"%p - %p - %p",d,d+1,d+2);
    打印结果:
    0x7ffeefbff4c0 - 0x7ffeefbff4c0 - 0x7ffeefbff4c4
    0x7ffeefbff4c0 - 0x7ffeefbff4c4 - 0x7ffeefbff4c8
    mark: 数组指针:数组的地址就是数组内第一个元素的指针地址。
    第二次打印的数据 指针偏移;int 在内存中占 4个字节,所以每次都会加4.
     for (int i = 0; i<4; i++) {
                // int value = c[i];
                int value = *(d+i);
                LGNSLog(@"%d",value);
            }
    打印结果:1,2,3,4
    使用指针打印数据;
    
    我们也可以打印一下对象的内存结构
    x/4gx 0x7ffeefbff4c0
    0x7ffeefbff4c0: 0x0000000200000001 0x0000000400000003
    0x7ffeefbff4d0: 0x00007ffeefbff4f0 0xfa3a5ced5c6300a3
    ------ 内存存储:小端存储;-------
    
    

    类的结构是什么样的

    class 继承自 objc_class ,objc_class 继承自 objc_object
    类、对象:万物皆对象
    1:typedef struct objc_class *Class;
    2:结构:
    struct objc_class : objc_object {
        // Class ISA; // 8字节 --隐藏的class的ISA 是来源父类的 👇
        Class superclass; // 8字节
        cache_t cache;    // 16 不是8   因为cache_t 是个指针      // formerly cache pointer and vtable
        class_data_bits_t bits;    // class_rw_t * plus custom rr/alloc flags
    
        class_rw_t *data() { 
            return bits.data();
        }.......and so on
    
    /// Represents an instance of a class.
    struct objc_object {
        Class _Nonnull isa  OBJC_ISA_AVAILABILITY;
    };
    父类的里面的class的ISA👆
    3:  class_rw_t  也是一个结构体 里面存放着
    a:  method_array_t
    b:  property_array_t
    c:  protocol_array_t
    
    struct class_rw_t {
        // Be warned that Symbolication knows the layout of this structure.
        uint32_t flags;
        uint32_t version;
    
        const class_ro_t *ro;
    
        method_array_t methods;
        property_array_t properties;
        protocol_array_t protocols;
    
        Class firstSubclass;
        Class nextSiblingClass;
    
        char *demangledName;
    
    #if SUPPORT_INDEXED_ISA
        uint32_t index;
    #endif
    
    
    ###nsobject:
    
    @interface NSObject <NSObject> {
    #pragma clang diagnostic push
    #pragma clang diagnostic ignored "-Wobjc-interface-ivars"
        Class isa  OBJC_ISA_AVAILABILITY;
    #pragma clang diagnostic pop
    }
    
    打印当前的对象的内存结构    
    LGPerson *person = [LGPerson alloc];        
    Class pClass     = object_getClass(person);
    
     x/4gx pClass
    0x1000023b0: 0x001d800100002389 0x0000000100b37140
    0x1000023c0: 0x00000001003da260 0x0000000000000000
    Mark:0x001d800100002389 --->第一个是ISA 
                 0x0000000100b37140 --->superclass
                 0x00000001003da260 ---> cache_t 
                 0x0000000000000000 --->bits 未赋值的bits
    这就是类的结构;  
    /**
    define ISA_MASK        0x0000000ffffffff8ULL
    **/
    po  0x001d800100002389 & ISA_MASK 就是当前的ISA指向的类
    po 0x001d800100002389 & 0x0000000ffffffff8
    打印结果:
    LGPerson
    
    /-----------/
    打印
    po 0x1000023b8 从0x1000023b0 地址加8就是superclass
    <NSObject: 0x1000023b8>
    
    ### class_data_bits_t :【**】
    (lldb)x/4gx pClass
    0x1000023d0: 0x001d8001000023a9 0x0000000100b37140
    0x1000023e0: 0x00000001003da260 0x0000000000000000
    (lldb)p (class_data_bits_t*)0x1000023f0
    (class_data_bits_t *) $1 = 0x00000001000023f0
    ====
    p $1->data()
    (class_rw_t *) $2 = 0x0000000101020950
    
    p *$2 看rw的存储结构
    (class_rw_t) $3 = {
      flags = 2148139008
      version = 0
      ro = 0x0000000100002328
      methods = {
        list_array_tt<method_t, method_list_t> = {
           = {
            list = 0x0000000100002260
            arrayAndFlag = 4294976096
          }
        }
      }
      properties = {
        list_array_tt<property_t, property_list_t> = {
           = {
            list = 0x0000000100002310
            arrayAndFlag = 4294976272
          }
        }
      }
      protocols = {
        list_array_tt<unsigned long, protocol_list_t> = {
           = {
            list = 0x0000000000000000
            arrayAndFlag = 0
          }
        }
      }
      firstSubclass = nil
      nextSiblingClass = NSUUID
      demangledName = 0x0000000000000000
    }
    p $3.properties  里面是个二位数组
    (property_array_t) $4 = {
      list_array_tt<property_t, property_list_t> = {
         = {
          list = 0x0000000100002310
          arrayAndFlag = 4294976272
        }
      }
    }
    
    p $4.list
    (property_list_t *) $5 = 0x0000000100002310
    
     p $5.first
    (property_t) $6 = (name = "nickName", attributes = "T@\"NSString\",C,N,V_nickName")
      Fix-it applied, fixed expression was: 
        $5->first
    查看ro 存的东西
     p *$3.ro
    (const class_ro_t) $7 = {
      flags = 388
      instanceStart = 8
      instanceSize = 24
      reserved = 0
      ivarLayout = 0x0000000100001f84 "\x02"
      name = 0x0000000100001f7b "LGPerson"
      baseMethodList = 0x0000000100002260
      baseProtocols = 0x0000000000000000
      ivars = 0x00000001000022c8
      weakIvarLayout = 0x0000000000000000
      baseProperties = 0x0000000100002310
    }
    
    p *$7.baseProperties ------>属性
    (property_list_t) $8 = {
      entsize_list_tt<property_t, property_list_t, 0> = {
        entsizeAndFlags = 16
        count = 1
        first = (name = "nickName", attributes = "T@\"NSString\",C,N,V_nickName")
      }
    }
     p *$7.ivars   ----->-成员变量
    (const ivar_list_t) $10 = {
      entsize_list_tt<ivar_t, ivar_list_t, 0> = {
        entsizeAndFlags = 32
        count = 2
        first = {
          offset = 0x0000000100002398
          name = 0x0000000100001e54 "hobby"
          type = 0x0000000100001fa1 "@\"NSString\""
          alignment_raw = 3
          size = 8
        }
      }
    }
    
    p $10.get(1)   -- 属性与成员变量的区别
    (ivar_t) $11 = {
      offset = 0x00000001000023a0
      name = 0x0000000100001e5a "_nickName"
      type = 0x0000000100001fa1 "@\"NSString\""
      alignment_raw = 3
      size = 8
    }
    
    属性 存在了 class -> objc_class -> class_data_bits_t ->  property_list_t ->
                             class -> objc_class -> class_data_bits_t ->  class_ro_t -> {
    baseProperties,属性相关
    ivars:成员变量
    }
    
    mark:objc_class 和NSObject 的区别
    前者是底层的C的写法 NSObject 是oc的写法,是oc的封装方法;
    

    相关文章

      网友评论

          本文标题:类的结构分析

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