iOS|类

前言

在 iOS 开发中,类是一个重要的概念,类、类对象和元类这些概念共同构成了 Objective-C 的核心,为我们提供了一种强大的方式来组织和操作代码。我将说一下我理解下的类,并深入探讨这些概念的含义和作用。

一、类

在 Objective-C 中,类可以理解为一种模板,它定义了对象的结构和行为。类是定义对象的抽象,它包括实例变量(成员变量)和方法。每个对象都是某个类的实例。

二、类对象

类对象是表示类的对象。每个类都有一个关联的类对象,这个类对象在运行时由系统自动创建。类对象存储了有关类的元数据信息,如方法列表、属性列表、父类引用等。它还可以用于创建类的实例和执行类方法。

看看下面的personClass1personClass2有什么区别

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 关于类这种体系结构允许其在运行时动态地创建类、对象和方法,来进行反射式编程。它也允许继承、多态和动态派发等面向对象编程特性。深入理类、类对象和元类这些概念有助于理解继承关系和多态的工作原理,也能有助于我们做一下高级编程开发,例如可以在元类中添加或替换类方法,从而定制类对象的行为。

相关推荐
Rattenking1 分钟前
node - npm常用命令和package.json说明
前端·npm·json
Easonmax1 分钟前
【HTML5】html5开篇基础(1)
前端·html·html5
For. tomorrow5 分钟前
Vue3中el-table组件实现分页,多选以及回显
前端·vue.js·elementui
布瑞泽的童话32 分钟前
无需切换平台?TuneFree如何搜罗所有你爱的音乐
前端·vue.js·后端·开源
白鹭凡44 分钟前
react 甘特图之旅
前端·react.js·甘特图
2401_862886781 小时前
蓝禾,汤臣倍健,三七互娱,得物,顺丰,快手,游卡,oppo,康冠科技,途游游戏,埃科光电25秋招内推
前端·c++·python·算法·游戏
书中自有妍如玉1 小时前
layui时间选择器选择周 日月季度年
前端·javascript·layui
Riesenzahn1 小时前
canvas生成图片有没有跨域问题?如果有如何解决?
前端·javascript
f8979070701 小时前
layui 可以使点击图片放大
前端·javascript·layui