美文网首页
11-OC 对象的本质

11-OC 对象的本质

作者: Rumbles | 来源:发表于2019-06-05 16:53 被阅读0次

    1.OC 对象本质是结构体

    #import <Foundation/Foundation.h>
    #import <malloc/malloc.h>
    #import <objc/runtime.h>
    
    //struct NSObject_IMPL
    //{
    //    Class isa;
    //};
    //
    //struct MJPerson_IMPL
    //{
    //    struct NSObject_IMPL NSObject_IVARS; // 8
    //    int _age; // 4
    //    int _height; // 4
    //    int _no; // 4
    //}; // 24
    
    struct NSObject_IMPL {
        Class isa;
    };
    
    struct MJPerson_IMPL {
        struct NSObject_IMPL NSObject_IVARS;
        int _age;
        int _height;
        int _no;
    }; // 计算结构体大小,内存对齐,24
    
    //struct MJStudent_IMPL
    //{
    //    struct MJPerson_IMPL MJPerson_IVARS;
    //    int _weight;
    //};
    
    @interface MJPerson : NSObject
    {
        int _age;
        int _height;
        int _no;
    }
    @end
    
    //@interface MJStudent : MJPerson
    //{
    //    int _weight;
    //}
    //@end
    
    @implementation MJPerson
    
    @end
    
    int main(int argc, const char * argv[]) {
        @autoreleasepool {
            MJPerson *p = [[MJPerson alloc] init];
            
            NSLog(@"%zd", sizeof(struct MJPerson_IMPL)); // 24。类型占用的内存大小
            
            NSLog(@"%zd %zd",
                  class_getInstanceSize([MJPerson class]), // 24 所有成员变量占用的内存大小
                  malloc_size((__bridge const void *)(p))); // 32。MJPerson 占用的内存大小
        }
    ///>为什么是32呢?
    24正常 是因为结构体内存对齐
    
    传到底层代码为24 但是系统分配给我们是32 是因为什么呢? 操作系统的内存对齐OC里面都是16的倍数。16   32   48   64  80  96  112   128    144  160  176  182  208。224  240。256
    所以就分配给我们。32字节  
        return 0;
    }
    一个OC对象至少占用 16个字节。因为isa指针占用的字节数是8字节  儿系统规定至少为16个字节
    

    苹果会自动对属性和成员变量进行分别重排从而优化内存 就是重排序 是内存变小

    对象存储的信息包括。变量的值。isa

    2.一个类只切只有一个类对象 里面存储的对象方法信息 成员变量的类型 名字

            NSObject *object1 = [[NSObject alloc] init];
            NSObject *object2 = [[NSObject alloc] init];
            
            Class objectClass1 = [object1 class];
            Class objectClass2 = [object2 class];
            Class objectClass3 = object_getClass(object1); ///> 返回isa指针
            Class objectClass4 = object_getClass(object2);
            Class objectClass5 = [NSObject class];
            
            NSLog(@"%p %p",
                  object1,
                  object2);
            
            NSLog(@"%p %p %p %p %p",
                  objectClass1,
                  objectClass2,
                  objectClass3,
                  objectClass4,
                  objectClass5); 输出的都一样
    

    3.元类对象 类方法信息

            Class objectMetaClass = object_getClass([object2 class]);
            Class objectMetaClass = object_getClass(objectClass5);
            Class objectMetaClass2 = [[[NSObject class] class] class];
    /*
     1.Class objc_getClass(const char *aClassName)
     1> 传入字符串类名
     2> 返回对应的类对象
     
     2.Class object_getClass(id obj)
     1> 传入的obj可能是instance对象、class对象、meta-class对象
     2> 返回值
     a) 如果是instance对象,返回class对象
     b) 如果是class对象,返回meta-class对象
     c) 如果是meta-class对象,返回NSObject(基类)的meta-class对象
     
     3.- (Class)class、+ (Class)class
     1> 返回的就是类对象
     
     - (Class) {
         return self->isa;
     }
     
     + (Class) {
         return self;
     }
     */
    
    基本的类成员变量结构
    struct ivar_t {
        int32_t *offset;
        const char *name;
        const char *type;
        //...
    }
    

    4.为什么Objective-C类不能动态添加成员变量

    category添加属性使用运行时 仅仅是添加了set get方法 但是不会添加实力变量
    

    5.Instance的isa指针指向哪里

    指向类对象。用来寻找对象方法
    类对象的isa指针指向元类对象 用来寻找类方法
    
    类对象的superClass 和 元类对象的superClass
    
    子类对象调用父类的对象方法
    先用子类的isa找到子类的类对象。然后去找找不到 在用superClass指针去父类里面寻找
    
    父类的superclass指针 
    对象方法找的是 类对象 类对象的superClass 找的是父类对象
    类方法找的是元类对象
    
    元类对象的isa指向根元类  跟元类也指向根元类
    
    NSObject的superClass指向的是nil
    NSObject 元类的superClass指向的是NSObject这个类
    
    类方法的寻找轨迹。如果在跟元类里面都没有这个方法 会去跟类的对象方法里面寻找 没有在报错
    
    image.png

    6.OC的类信息存放在哪里

    类方法存放在元类对象中
    成员变量 属性  对象方法 协议  放在类对象中
    成员变量的具体值存放在 实例对象中
    main函数加载累的信息的时候 就会把类对象存放在内存中
    类对象 元类对象在内存里面只有一份
    

    Objective-C类成员变量深度剖析

    相关文章

      网友评论

          本文标题:11-OC 对象的本质

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