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]
- isa指针
- superclass指针
- 类的属性信息(property)、类的对象方法信息(instance method)、类的协议信息(protocal)、类的成员变量信息(ivar)(存储成员变量的类型,名字因为只需要存储一份,对于哪一个实例对象,名字和类型都是一样的。不存储成员变量的值,因为每一个实例对象都有自己的值,成员变量的值存在实例对象中)
Meta-Class:元类对象
Metadata:元数据(描述数据的数据)
Meta-Class:元类对象(描述类的对象)
元类对象存储类方法。每个类只有一个元类对象。
元类对象和类对象的结构是一样的,都是Class类型,但用途不同。
获取元类对象
object_getClass([NSObject class])
- isa指针
- superclass指针
- 类的方法信息
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相互结合,实现了方法的查找
- instance对象调用对象方法,通过isa找到class对象。如果的lass对象没有调用的对象方法,则当前类对象通过superclass找到父类的class对象,开始查找父类的方法列表。直到找到对象方法并开始调用。
- class对象调用类方法,通过isa找到meta-class对象,如果meta-class对象没有调用的类方法,则通过superclass找到当前meta-class对象的父类对象的meta-class对象,并查找方法列表。直到找到类方法并调用。
参考图片:
![](https://img.haomeiwen.com/i1429750/565fd4e303ae8b61.png)
![](https://img.haomeiwen.com/i1429750/9d6a73cb5bfb3f90.png)
网友评论