类 及 对象 在OC中的定义
定义了 Class 为类结构体指针 typedef struct objc_class *Class;
对象结构体定义: struct objc_object { Class _Nonnull isa ; //isa指针 };
类结构体的定义: struct objc_class { Class _Nonnull isa ; //isa指针 Class _Nullable super_class ; //父类指针 const char * _Nonnull name ; //类名 long version ; //版本 long info ; //类信息 long instance_size; //该类的实例对象大小 struct objc_ivar_list * _Nullable ivars; //类的成员列表 struct objc_method_list * _Nullable * _Nullable methodLists; //方法列表 struct objc_cache * _Nonnull cache; //方法缓存列表 struct objc_protocol_list * _Nullable protocols; //协议列表 };
关于 isa指针 以及 元类
由上面的对象和类的结构体定义看到,类和对象的结构体里都包含一个isa指针,且isa都是class类型的指针。对象中isa指针指向该对象的类对象,而类对象中的isa指针指向的是该类的 元类 。isa的指针是了类类型的指针,其指向的结构体就是objc_class 由此可见 元类 中也包含一个isa指针,而这个isa指针指向基类的 元类。总所周知oc中所有类型的基类都是NSObject,而NSObject的元类的isa指针又指向哪里,NSObject往上已没有任何基类,因此基类的isa指针指向的就是期基类本身。
由下图可见对象 类 元类 中isa指针的指向 (来源:github.com/FrizzleFur/…)
元类 (类对象的类) 元类中存放了类方法,对类方法的调用实际就是向元类发送消息。
思考:元类存在的必要性,类的中含有实例方法和类方法 为什么不把类方法和实例方法统一存储到类对象下的方法列表中而是分开存储?
我觉得元类存在必要性其一应该是为了存储类方法。但是为什么不把类方法和实例方法放到一起存储在一个方法类表中呢?其原因应该是在于类方法和实例方法的根本区别: 1、静态方法在程序开始时生成内存,实例方法在程序运行中生成内存,所以静态方法可以直接调用。 2、实例方法要先成生实例,通过实例调用方法,静态速度很快,但是多了会占内存。 3、静态内存是连续的,因为是在程序开始时就生成了,而实例申请的是离散的空间,所以当然没有静态方法快,而且静态内存是有限制的,太多了程序会启动不了。 4、类方法常驻内存,实例方法不是,所以类方法效率高但占内存。 5、类方法在堆上分配内存,实例方法在堆栈上。 6、实例方法需要先创建实例才可以调用,比较麻烦,类方法不用,比较简单。 7、类方法,也称静态方法,指的是用static关键字修饰的方法。此方法属类本身的方法,不属于类的某一个实例(对象)。 8、类方法中不可直接使用实例变量。其调用方式有三种:可直接调用、类名.方法名、对象名.方法名。 9、实例方法指的是不用static关键字修饰的方法。每个实例对象都有自身的实例方法,互相独立,不共享一个。其调用方式只能是对象名+方法名。【来自网络】 如果放在一起就无法区分类方法和实例方法了。
链接: 类和元类 :github.com/FrizzleFur/… Objective-C Runtime 运行时之一:类与对象:www.cocoachina.com/articles/10…