OC对象的种类

2021-10-27  本文已影响0人  爱学的小姚

OC中的对象主要分为3种

1、instance对象(实例对象)
2、class对象(类对象)
3、meta-class对象(元类对象)

1、instance对象(实例对象)

实例对象是类alloc出来的对象,每次调用alloc都会调用新的instance对象,关于实例对象的详细介绍,可以参考我之前写的文章

2、class对象(类对象)

一个类的类对象在内存中只有一份,获取类对象的方式有以下几种:

#import <Foundation/Foundation.h>
#import <objc/runtime.h>

typedef struct objc_class *Class;
int main(int argc, const char * argv[]) {
    @autoreleasepool {
        
        NSObject *objc = [[NSObject alloc] init];
        Class objcClass1 = [objc class];
        Class objcClass2 = [NSObject class];
        Class objcClass3 = object_getClass(objc);
        
        NSLog(@"objcClass1 = %p", objcClass1);
        NSLog(@"objcClass2 = %p", objcClass2);
        NSLog(@"objcClass3 = %p", objcClass3);
    }
    return 0;
}

打印结果可知,类对象的地址都是同一个,我们窥探Class的结构,下载源码( 本人使用的是818版本objc4-818.2),class的结构为:

//  class为objc_class *类型的结构体
typedef struct objc_class *Class;

//  objc-private.h
struct objc_object {
    isa_t isa;
}

//  objc-runtime-new.h
struct objc_class : objc_object {
    ......
    // 包含Class ISA;
    Class superclass;
    cache_t cache;      //  方法缓存         
    class_data_bits_t bits;    //  & FAST_DATA_MASK之后,在class_rw_t *中获取类的具体信息
    ......
}

struct class_rw_t {
    uint32_t flags;
    uint32_t version;
    const class_ro_t *ro;
    method list t * methods;   // 方法列表
    property_list_t *properties;   // 属性列表
    const protocol _list_t * protocols;   // 协议列表
    Class firstSubclass:
    Class nextSiblingClass;
    char *demangledName;
}

struct class_ro_t {
    uint32_t flags;
    uint32_t instanceStart;
    uint32_t instanceSize;  //  instance对象占用的内存空间
#ifdef  __LP64__
    uint32_t reserved;
#endif
    const uint8_t * ivarLayout;
    const char *name;  // 类名
    method_list_t * basevethodList;
    protocol_list_t * baseProtocols;
    const ivar_list_t * ivars; // 成员变量列表
    const_uint8_t * weakIvarLayout;
    property_list_t *baseProperties;
}

该数据结构后面会讲到。由上面数据结构可以知道,类对象在内存中存储:

1、isa指针
2、superclass指针
3、类的属性信息(@property)
4、类的对象方法信息(instance method)
5、类的协议信息(protocol)
6、类的成员变量信息(ivar 记录成员)
...

3、meta-class对象(元类对象)

元类对象的数据结构实际上和类对象的数据结构一致。获取meta-class对象的方式:

Class objcMetaClass = object_getClass([NSObject class]);

注意:class方法,底层实现是return self,调用[[NSObject class] class],返回的依然是类对象,不是元类对象。实现class的源码为:

+ (Class)class {
    return self;
}

- (Class)class {
    return object_getClass(self);
}

一个类的类对象在内存中只有一份,元类对象在内存中存储:

1、isa指针
2、superclass指针
3、类的类方法信息(class method)
...
上一篇 下一篇

猜你喜欢

热点阅读