OC对象的本质

274 阅读2分钟

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类型的类对象

所以,说了这么多,OC对象的本质是什么呢?其实就是结构体,里边实现了各种黑魔法的结构体