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

相关推荐
一斤代码2 小时前
vue3 下载图片(标签内容可转图)
前端·javascript·vue
中微子2 小时前
React Router 源码深度剖析解决面试中的深层次问题
前端·react.js
光影少年2 小时前
从前端转go开发的学习路线
前端·学习·golang
中微子2 小时前
React Router 面试指南:从基础到实战
前端·react.js·前端框架
3Katrina2 小时前
深入理解 useLayoutEffect:解决 UI "闪烁"问题的利器
前端·javascript·面试
前端_学习之路3 小时前
React--Fiber 架构
前端·react.js·架构
伍哥的传说4 小时前
React 实现五子棋人机对战小游戏
前端·javascript·react.js·前端框架·node.js·ecmascript·js
qq_424409194 小时前
uniapp的app项目,某个页面长时间无操作,返回首页
前端·vue.js·uni-app
我在北京coding4 小时前
element el-table渲染二维对象数组
前端·javascript·vue.js
2501_915918414 小时前
Fiddler中文版全面评测:功能亮点、使用场景与中文网资源整合指南
android·ios·小程序·https·uni-app·iphone·webview