美文网首页iOS底层原理
小码哥底层原理笔记:OC对象的分类(一)

小码哥底层原理笔记:OC对象的分类(一)

作者: chilim | 来源:发表于2020-04-28 15:52 被阅读0次

    OC的对象分为三类:

    • instance对象(实例对象)
    • class对象(类对象)
    • meta-class对象(元类对象)

    实例对象

    instance对象就是通过类alloc出来的对象,每次调用alloc都会产生新的instance对象,每个实例对象的内存地址都不一样

    int main(int argc, char * argv[]) {
        @autoreleasepool {
    //实例对象
            NSObject *object1 = [[NSObject alloc] init];
            NSObject *object2 = [[NSObject alloc] init];
            //实例对象内存地址打印
            NSLog(@"%p %p",object1,object2);
            //0x28039c180 0x28039c170,内存地址不一样。说明实例对象是不同的
        }
        return 0;
    }
    

    instance实例对象只保存成员变量

    class类对象

    通过class方法或runtime方法得到一个class对象

    int main(int argc, char * argv[]) {
        @autoreleasepool {
            //类对象,一个类对象是唯一的,在内存中只有一份
            Class objectClass1 = [object1 class];
            Class objectClass2 = [object2 class];
            Class objectClass3 = [NSObject class];
            
            Class objectClass4 = object_getClass(object1);
            Class objectClass5 = object_getClass(object2);
            //类对象内存地址打印
            NSLog(@"%p %p %p %p %p",
                  objectClass1,objectClass2,objectClass3,objectClass4,objectClass5);
            //0x1e3d9beb0 0x1e3d9beb0 0x1e3d9beb0 0x1e3d9beb0 0x1e3d9beb0,内存地址都一样,说明在内存中只有一个类对象
        }
        return 0;
    }
    

    可以看到不管用什么方法生成的类对象的内存地址都是一样的,说明每一个类在内存中有且只有一个class对象。
    之前提到instance实例对象不保存方法,只保存成员变量。方法保存在class类对象中
    类对象中主要包含:

    • isa指针
    • superclass指针
    • 类的属性信息(@property),如成员变量的类型
    • 类的对象方法信息
    • 类的协议信息(protocol)
    • 类的成员变量信息(ivar)
      成员变量的值是存储在实例对象中的,因为只有当我们创建实例对象的时候才为成员变赋值。但是成员变量叫什么名字,是什么类型,只需要有一份就可以了。所以存储在class对象中。

    元类对象 meta-class

    通过runtime方法object_getClass传入一个类对象得到元类对象

    int main(int argc, char * argv[]) {
        @autoreleasepool {
            NSObject *object1 = [[NSObject alloc] init];
            NSObject *object2 = [[NSObject alloc] init];
            //元类对象,将类对象当作参数,获得元类对象,每个类中也只有一个元类对象,在内存是唯一的
            Class objectMetaClass1 = object_getClass([NSObject class]);
            Class objectMetaClass2 = object_getClass([NSObject class]);
            NSLog(@"metaclass - %p %p",objectMetaClass1,objectMetaClass2);
            //0x1e3d9be60 0x1e3d9be60
        }
        return 0;
    }
    

    通过打印的内存地址可以知道 每个类中也只有一个元类对象,在内存是唯一的
    meta-class元类对象保存的内容与类对象类似,主要是

    • isa指针
    • superclass指针
    • 类的类方法信息

    注:我们知道用class方法可以获得class类对象,但是类对象调用class方法依旧是类对象,而不是元类对象

    Class objectClass3 = [NSObject class];//这是一个类对象
    Class objectClass2 = [[NSObject class] class];//这是一个类对象,而不是元类对象
    NSLog(@"class - %p %p", objectClass3, objectClass2);//class - 0x1e3d9be60,0x1e3d9be60
    

    以上代码可以看到,类对象调用class方法后还是一个类对象,而并不是元类对象,只有通过runtime方法object_getClass传入一个类对象才得到元类对象

    总结:每一个类可以有多个实例对象,但是对应只有一个类对象和元类对象。

    相关文章

      网友评论

        本文标题:小码哥底层原理笔记:OC对象的分类(一)

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