实例对象:就是我们通常的类的实例化的对象比如
Obj * obj = [Obj new];
,那么这个obj
就是一个实例对象
类对象:这个时候是否有点奇怪,其实类也是一个对象,比如Obj
其实也是一个对象
元类:其实就是 类对象的isa指向的类。
- 可能前面的定义有点模糊,下面我们看看,runtime里面的 实例的结构体和 类的结构体
----------------------------------------------------
//类的实例
typedef struct objc_object *id;
/// Represents an instance of a class.
struct objc_object {
Class isa OBJC_ISA_AVAILABILITY;
};
这里有个isa 指针,指向的就是 当前实例的类对象
----------------------------------------------------
/// An opaque type that represents an Objective-C class.
typedef struct objc_class *Class;
struct objc_class {
Class isa OBJC_ISA_AVAILABILITY; //
#if !__OBJC2__
Class super_class OBJC2_UNAVAILABLE;//父类
const char *name OBJC2_UNAVAILABLE;//类名
long version OBJC2_UNAVAILABLE;
long info OBJC2_UNAVAILABLE;
long instance_size OBJC2_UNAVAILABLE;//实例大小
struct objc_ivar_list *ivars OBJC2_UNAVAILABLE;//成员变量列表
struct objc_method_list **methodLists OBJC2_UNAVAILABLE;//方法列表
struct objc_cache *cache OBJC2_UNAVAILABLE;//方法缓存
struct objc_protocol_list *protocols OBJC2_UNAVAILABLE;//协议列表
#endif
} OBJC2_UNAVAILABLE;
/* Use `Class` instead of `struct objc_class *` */
这里也是有个isa 指针,其实这个isa 指向的就是 **元类**
----------------------------------------------------
2、下面我们来看一个例子,方便更好的来理解元类
的概念
同时我们首先理解几个知识点
object_getClass(实例对象) == [实例对象 class]
[类对象 class] == 类对象
object_getClass(类对象) == 类对象的isa == 元类
object_getClass(类对象) != [类对象 class]
添加方法,其实是在 类对象/实例对象
中的isa指针的类中添加
首先定义一个 Obj的类
----------------------------------------------------
@interface Obj : NSObject
//实例方法
- (void)print1;
//类对象方法
+ (void)classPrint;
@end
@implementation Obj
//这里不去实现它,后面我们会通过runtime的知识添加方法
@end
下面我们切换当控制器中
----------------------------------------------------
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
Obj * obj = [Obj new];
Class class11 = object_getClass(obj);
Class class12 = [obj class]; //这个是获取当前的类的对象,实例是就是isa指向的类对象,但是类对象指向确是自己本身
NSLog(@"class1 :%p,class2 = %p",class11,class12);
//class1 :0x1077b8f00,class2 = 0x1077b8f00
Class class21 = object_getClass(class11);//Son的Class的元类
Class class22 = [class12 class];//还是本身Son的Class
Class classMeta= objc_getMetaClass(object_getClassName(obj));//Son的Class元类
NSLog(@"class1 :%p,class2 = %p,classMeta = %p",class21,class22,classMeta);
//class1 :0x1077b8ed8,class2 = 0x1077b8f00,classMeta = 0x1077b8ed8
//在给对象或者类添加方法的时候,其实是给isa 指向的类添加方法,就是说 一个普通的对象是给它的class添加方法,而 一个普通的类对象,需要添加方法其实是给它isa指向的 元类添加方法
//给obj实例对象 添加 方法
class_addMethod(class11, @selector(print1), (IMP)IMPFunc, NULL);
[obj print1];
//给obj的类对象添加方法
class_addMethod(class21, @selector(classPrint), (IMP)IMPMetaClassFunc, NULL);
[Obj classPrint];
}
void IMPFunc(id self ,SEL cmd) {
NSLog(@"print1");
}
void IMPMetaClassFunc(id self ,SEL cmd) {
NSLog(@"IMPMetaClassFunc");
}