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

相关推荐
IT_陈寒31 分钟前
Redis性能翻倍的5个冷门技巧,90%开发者都不知道第3个!
前端·人工智能·后端
jingling5552 小时前
vue | 在 Vue 3 项目中集成高德地图(AMap)
前端·javascript·vue.js
油丶酸萝卜别吃2 小时前
Vue3 中如何在 setup 语法糖下,通过 Layer 弹窗组件弹出自定义 Vue 组件?
前端·vue.js·arcgis
J***Q2928 小时前
Vue数据可视化
前端·vue.js·信息可视化
ttod_qzstudio10 小时前
深入理解 Vue 3 的 h 函数:构建动态 UI 的利器
前端·vue.js
_大龄10 小时前
前端解析excel
前端·excel
一叶茶11 小时前
移动端平板打开的三种模式。
前端·javascript
前端大卫11 小时前
一文搞懂 Webpack 分包:async、initial 与 all 的区别【附源码】
前端
Want59511 小时前
HTML音乐圣诞树
前端·html
老前端的功夫11 小时前
前端浏览器缓存深度解析:从网络请求到极致性能优化
前端·javascript·网络·缓存·性能优化