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)
...