前言
在 iOS 开发中,类是一个重要的概念,类、类对象和元类这些概念共同构成了 Objective-C 的核心,为我们提供了一种强大的方式来组织和操作代码。我将说一下我理解下的类,并深入探讨这些概念的含义和作用。
一、类
在 Objective-C 中,类可以理解为一种模板,它定义了对象的结构和行为。类是定义对象的抽象,它包括实例变量(成员变量)和方法。每个对象都是某个类的实例。
二、类对象
类对象是表示类的对象。每个类都有一个关联的类对象,这个类对象在运行时由系统自动创建。类对象存储了有关类的元数据信息,如方法列表、属性列表、父类引用等。它还可以用于创建类的实例和执行类方法。
看看下面的personClass1
和personClass2
有什么区别
objc
// 假设有一个自定义类 Person
@interface Person : NSObject
@end
Class personClass1 = [Person class];
Person *person = [[Person alloc] init];
Class personClass2 = [person class];
其实两者都是 Person 类的类对象,只不过后者是先创建 Person 类的实例,然后获取该实例的类对象。这种方式会额外创建一个实例对象,一般情况下不需要这样做。
三、元类(metaclass
)
元类(也叫metaclass
)是类对象的类,它用于描述类对象的行为。每个类对象都有一个关联的元类,它在运行时自动生成。元类包含类方法的定义,这些方法可用于类级别的操作。元类的父类通常是根类(NSObject 的元类)。
以下是获取元类的代码
objc
// 假设有一个自定义类 Person
@interface Person : NSObject
@end
// 获取 Person 类的类对象
Class personClass = [Person class];
// 获取 Person 类的类对象的元类(metaClass)
Class metaClass = object_getClass(personClass);
1.上面的代码中,Class(C是大写)是什么?
Class 是一种数据类型,用于表示类的类型。[Person class]
表示获取 Person 类的类对象,这个类对象的类型是 Class。
2.为什么Person 类的类对象和其元类的类型都是Class?
这是 Objective-C 运行时的设计决策,Objective-C 运行时采用了一种统一的模型,其中类对象和元类对象都是类的特殊实例,它们都是 Class 类型的对象。这种设计的好处是使运行时系统更加简单和一致。
3.Class类型里面的结构是怎样的?
Class 类型实际上是一个指向类对象的指针。类对象是一个结构体,它包含了有关类的元数据信息,包括方法、属性、实例变量等。虽然 Class 类型的具体实现可能会因编译器和操作系统而异,但通常来说,一个类对象的结构大致如下:
objc
typedef struct objc_class {
Class isa; // 指向元类的指针
Class superclass; // 指向父类的指针
const char *name; // 类的名称
size_t instanceSize; // 实例变量的大小
// ... 其他类信息 ...
Method *methodList; // 指向方法列表的指针
// ... 其他信息 ...
} *Class;
4.元类有继承关系吗?
直接上代码最直观,创建继承链:Men -> Person -> NSObject
objc
@interface Person : NSObject
@end
@interface Men : Person
@end
打印对应的实例对象、类对象、类对象的元类、元类的父类
objc
// NSObject实例对象
NSObject *object1 = [NSObject alloc];
// NSObject类
Class objectClass = object_getClass(object1);
// NSObject元类
Class metaClass = object_getClass(objectClass);
// NSObject元类的父类(根元类)
Class rootMetaClass = object_getClass(metaClass);
NSLog(@"\n%p 实例对象\n%p 类\n%p 元类\n%p 根元类\n",object1,objectClass,metaClass,rootMetaClass);
// 创建Person类的实例对象
Person *person = [[Person alloc] init];
// Person的类
Class PersonClass = object_getClass(person);
// Person的类的元类
Class pMetaClass = object_getClass(PersonClass);
// Person的类的元类的父类
Class pMetaSuperClass = class_getSuperclass(pMetaClass);
NSLog(@"\n%p Person实例对象\n%p Person的类\n%p Person的类的元类\n%p Person的类的元类的父类\n",person,PersonClass,pMetaClass,pMetaSuperClass);
// 创建Men类的实例对象
Men *men = [[Men alloc] init];
// Men的类
Class menClass = object_getClass(men);
// Men的类的元类
Class mMetaClass = object_getClass(menClass);
// Men的类的元类的父类
Class mMetaSuperClass = class_getSuperclass(mMetaClass);
NSLog(@"\n%p Men实例对象\n%p Men的类\n%p Men的类的元类\n%p Men的类的元类的父类",men,menClass,mMetaClass,mMetaSuperClass);

从打印结果可以得出如下结论:
Men
的类对象的元类的父类就是Person
的类对象的元类,即两者的元类之间有继承关系NSObject
作为所有类的基类,其元类就是终点,也就是根元类- 根元类(
Root Metaclass
)是元类(Metaclass
)的最顶层 NSObject
作为所有类的基类,没有父类,或者说父类为nil,即superclass是nil
总结
Objective-C 关于类这种体系结构允许其在运行时动态地创建类、对象和方法,来进行反射式编程。它也允许继承、多态和动态派发等面向对象编程特性。深入理类、类对象和元类这些概念有助于理解继承关系和多态的工作原理,也能有助于我们做一下高级编程开发,例如可以在元类中添加或替换类方法,从而定制类对象的行为。