聊一聊对象(二)

2020-12-22  本文已影响0人  晨阳Xia

sizeof() // 传的类型.是个运算符并不是函数即便是我传了一个对象,也是对类型进行计算。因为编译器编译期间就决定了。c语言是编译器决定的。用它只能计算类型的大小。没法计算对象占用的内存。
Class_getInstanceSize() // 传的是实例。是一个函数。运行过程中决定的
malloc_size() // 函数,运行过程中决定的
new alloc copy mutableCopy 生成并持有对象

instance:(实例对象)对象就是通过alloc出来的对象,每次调用alloc都会产生新的instance对象。

获取类对象
[[NSObject alloc] init]
instance在内存中存储了那些信息?
只存储成员变量的具体值(isa成员变量是所有的实例对象都有的,每一个类都继承自nsonject,所以每一个实例对象都存在isa),不存储方法。isa的地址就是实例对象的地址,因为他排在最前面。

class(类对象)每个类在内存中有且只有一个类对象。

类对象在内存中存储什么信息?
获取类对象
object_getClass(object)
或:
[NSObject class]

Meta-Class:元类对象

Metadata:元数据(描述数据的数据)
Meta-Class:元类对象(描述类的对象)
元类对象存储类方法。每个类只有一个元类对象。
元类对象和类对象的结构是一样的,都是Class类型,但用途不同。
获取元类对象
object_getClass([NSObject class])

Class object_getClass(id obj) 和 objc_getClass

Class object_getClass(id obj)
{
    if (obj) return obj->getIsa();
    else return Nil;
}
实例对象的isa指向类对象,类对象的isa指向元类对象。元类对象的isa指向基类的元类对象。
所以object_getClass,如果传入的是实例对象,得到的就是instance对象,如果传入的是class对象,得到的就是mate-class对象,如果传入的是meta-class对象,得到的就是base-meta-class对象。

区别于object_getClass
objc_getClass。
传入的是字符串的类名,返回的只是类对象。

对象的isa指针指向哪里

实例对象的isa指向class对象,class对象的isa指向meta-class对象
superclass指向父class对象

instance对象存储的信息、class对象存储的信息、meta-class对象存储的信息

instance 对象

struct NSObject_IMPL {
 Class isa;
};

struct XSYPerson_IMPL {
 struct NSObject_IMPL NSObject_IVARS;
 int _age;
};

class对象

typedef struct objc_class *Class;
// 新版本的class结构体已经弃用此结构
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;


meta-class对象

isa和superclass的区别

instance对象、class对象、meta-class对象都有isa指针
class对象和meta-class对象都有superclass指针

那么instance对象、class对象、meta-class对象他们之间的isa有什么区别呢?

关于isa

instance对象的isa指向instance对象的class对象
class对象的isa指向class对象的meta-class对象
meta-class对象的isa指向基类meta-class对象。
基类的meta-class的superclass指向基类的class对象
由此可以解释:instance值存储属性值,不存储方法,调用对象方法的时候通过isa找到class对象,在class方法列表中取得方法。class对象中不存储类方法,调用类方法的时候通过isa找到元类对象,从而调用类方法。

关于superclass

superclass指向的是类对象。
class对象的superclass指向父类的class对象
meta-class的superclass指向父类的meta-class对象
在这里,meta-class对象的isa和superclass的指向有个区别,meta-class的isa指向的是base-meta-class对象,而meta-class的superclass指向的是父类的meta-class对象。
base-meta-class对象的meta-class指向自己

isa和superclass相互结合,实现了方法的查找
  1. instance对象调用对象方法,通过isa找到class对象。如果的lass对象没有调用的对象方法,则当前类对象通过superclass找到父类的class对象,开始查找父类的方法列表。直到找到对象方法并开始调用。
  2. class对象调用类方法,通过isa找到meta-class对象,如果meta-class对象没有调用的类方法,则通过superclass找到当前meta-class对象的父类对象的meta-class对象,并查找方法列表。直到找到类方法并调用。

参考图片:


image.png

image.png
上一篇 下一篇

猜你喜欢

热点阅读