元类

1.runtime

runtime,直译过来是运行时,它是一套底层的C语言API,包含很多强大实用的C语言数据类型和C语言函数。我们的OC代码在运行阶段都是基于runtime环境才能正常运行的。

2.常用场景

  • 发送消息;
  • 读取成员变量;
  • 动态为某个类增加属性;
  • 交换类中的方法、动态为某个类添加方法;
  • 动态创建、删除、修改一个类;

3.对象

OC中,含有isa指针且该指针可以正确指向类的数据结构,都可以视为对象。

下面是objc.h中的相关定义:

#if !OBJC_TYPES_DEFINED
/// An opaque type that represents an Objective-C class.
typedef struct objc_class *Class;

/// Represents an instance of a class.
struct objc_object {
Class isa  OBJC_ISA_AVAILABILITY;
};

/// A pointer to an instance of a class.
typedef struct objc_object *id;
#endif

objc_object结构体的定义可以看出:对象实质上是一个结构体,其结构体内含有isa指针,指向其所属的类。

4.类

下面是runtime.h中对的定义:

struct objc_class {
Class isa  OBJC_ISA_AVAILABILITY;       //指针

#if !__OBJC2__
Class super_class                       //父类;
const char *name                        //类名;
long version                                             //类的版本信息,默认为0;
long info                               //位标识;
long instance_size                      //类的实例变量大小;
struct objc_ivar_list *ivars            //类的成员变量链表;
struct objc_method_list **methodLists   //方法定义的链表;
struct objc_cache *cache                //方法缓存;
struct objc_protocol_list *protocols    //协议链表;
#endif

} OBJC2_UNAVAILABLE;

从结构体的定义来看,类也是以isa开始并指向类的数据结构。OC中类与元类在运行时都是objc_class类型,所以,类和元类也是一种对象

5.元类

1
NSObject *obj = [NSObject alloc];

5.1.实例对象

实例对象,instance object,是指从某个类实例化而来的对象,如示例中的obj

5.2.类对象

类对象,Class object,是指类作为对象时,称之为类对象。调用一个 “类方法” ,如 [NSObject alloc],实质上是向它的类对象(NSObject)发送了一个消息。类对象是由编译器创建的,任何继承自NSObject的类,它的实例对象中都有一个isa指针,指向它的类对象。

5.3.元类

元类,Metaclass,是类对象的isa指针所指向的类,类对象是元类的实例。

区分类对象与元类:

  • 类对象中保存的是关于其实例对象的信息(变量,实例方法、遵守的协议等);
  • 元类中保存的是关于类的信息(类方法,类的版本,名字等);

借用网上的一张图,演示元类与继承的封闭循环:

isa与superclass

图中实线是 super_class 指针,虚线是isa指针。

  • 实例对象是类的实例;
  • 类作为对象又是元类的实例;
  • 元类作为对象是根元类的实例;
  • 根元类是其自身的实例;
  • 根类的 superclass 为 nil;
  • 根元类的 superclass 为根类自己;

6.isa

isa 等价于 is kind of:

  • 实例对象的 isa 指向类对象;
  • 类对象的 isa 指向元类对象;
  • 元类对象的 isa 指向根元类;
  • 根元类对象的 isa 指向其自身;

7.相关函数

1
-class

对于实例对象,返回其 isa 指针指向的;对于类对象,返回其本身

1
object_getClass(id obj)

返回isa指针指向的内容。对实例对象,返回其 isa 指向的;对类对象,返回其对应的元类

1
objc_getMetaClass(const char *name)

返回对应的元类


相关参考:

#©Objective-C Runtime


元类
https://davidlii.cn/2017/08/22/runtime-metaclass.html
作者
Davidli
发布于
2017年8月22日
许可协议