Person类为例,他的本质为如下的结构体
struct NSObject_IMPL {
Class isa;
};
struct Person_IMPL {
struct NSObject_IMPL NSObject_IVARS;
int _age;
}
具体来说分三个
- instance 实例对象
- class 类对象
- meta-class 元类对象
1、instance 实例对象
他在内存中存储了
- 成员变量
- isa(所有实例对象都有的,包含在成员变量中)
- 没有存储方法
思考?问题?
1、为什么所有oc类都有isa?
因为都继承自NSObject。 isa的内存地址在最前,他的内存地址其实就是对象的内存地址,isa也是在结构体的最前
思考:实例对象中的isa的地址就是实例的地址,那isa的值是什么?是对应类对象的地址么?
2、class 类对象
获取方法
NSObject *obj1 = [[NSObject alloc] init];
NSObject *obj2 = [[NSObject alloc] init];
Class objcClass1 = [obj1 class];
Class objcClass2 = [NSObject class];
Class objcClass3 = object_getClass(obj1);
Class objcClass4 = object_getClass(obj2);
//包含
1、isa
2、superclass指针
3、属性信息
4、对象方法信息 (-开头)
5、协议信息
6、成员变量信息
......
源码如下
struct objc_class {
Class _Nonnull isa OBJC_ISA_AVAILABILITY;
#if !__OBJC2__
Class _Nullable super_class OBJC2_UNAVAILABLE;
const char * _Nonnull name OBJC2_UNAVAILABLE;
long version OBJC2_UNAVAILABLE;
long info OBJC2_UNAVAILABLE;
long instance_size OBJC2_UNAVAILABLE;
struct objc_ivar_list * _Nullable ivars OBJC2_UNAVAILABLE;
struct objc_method_list * _Nullable * _Nullable methodLists OBJC2_UNAVAILABLE;
struct objc_cache * _Nonnull cache OBJC2_UNAVAILABLE;
struct objc_protocol_list * _Nullable protocols OBJC2_UNAVAILABLE;
#endif
} OBJC2_UNAVAILABLE;
1、一个类的类对象,在内存中只有一份;
2、成员变量的类型等不变的信息也在类对象中;
3、meta-class 元类对象
获取
Class objcMetaClass = object_getClass([NSObject class]);
内部结构和类对象相同,都是object_class
1、isa指针
2、superclass指针
3、类方法 (+ class method)
...
4、object_getClass的内部实现
/***********************************************************************
* object_getClass.
* Locking: None. If you add locking, tell gdb (rdar://7516456).
**********************************************************************/
Class object_getClass(id obj)
{
if (obj) return obj->getIsa();
else return Nil;
}
static Class getClass(const char *name)
{
runtimeLock.assertLocked();
// Try name as-is
Class result = getClass_impl(name);
if (result) return result;
// Try Swift-mangled equivalent of the given name.
if (char *swName = copySwiftV1MangledName(name)) {
result = getClass_impl(swName);
free(swName);
return result;
}
return nil;
}
object_getClass是传入instance对象或者class对象或者meta-class对象
传入instance返回class对象;
传入class对象返回meta-class对象;
传入meta-class对象,返回NSObject的meta-class对象
getClass是根据一个字符串找到一个Class类型的类对象