iOS - isa、superclass指针,元类superclass指向基类本身(上)
instance对象,也称实例对象
class对象,也称类对象
meta-calss对象 也称元类对象
本文将探讨如下问题
通过 alloc之后的都是instance对象.这里还需要强调的是 instance对象不仅仅是NSObject对象,还有一个代理类NSProxy 也能创建instance对象
// 创建一个对象 NSObject* obj [NSObject alloc];
创建一个继承自NSObject的ClassObject类
- (void)viewDidLoad { [super viewDidLoad]; ClassObject *clsObj [[ClassObject alloc] init]; [self fetchClassWithClassObject:clsObj]; //获取class的所有方法 - (void)fetchClassWithClassObject:(ClassObject *)clsObj { Class objClass1 [clsObj class]; Class objClass2 [ClassObject class]; Class objClass3 object_getClass(clsObj); NSLog( \n objClass1 % \n objClass2 % \n objClass3 % \n ,NSStringFromClass(objClass1), NSStringFromClass(objClass2), NSStringFromClass(objClass3) ); NSLog( \n\n objClass1 %p \n objClass2 %p \n objClass3 %p , objClass1, objClass2, objClass3); //打印结果 2021-05-04 10:34:36.333929 0800 ClassDemo[26079:8911440] objClass1 ClassObject objClass2 ClassObject objClass3 ClassObject 2021-05-04 10:34:36.334052 0800 ClassDemo[26079:8911440] objClass1 0x109a61548 objClass2 0x109a61548 objClass3 0x109a61548
打印可见 不管用什么方式获取的class对象都是一样的 打印地址也一致 说明在项目中一个Class仅有一个对象 但是上面三种获取class的方式有什么不同呢
前两种是通过方法获取的 直接获取的是当前instance的Class 但是第三种方式不一样 这种方式获取的是当前instance的isa的值
可以这样做个实验 给clsObj添加一个kvo
[clsObj addObserver:self forKeyPath: class options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld context:nil];
打印结果变为
2021-05-04 10:54:32.415419 0800 ClassDemo[28990:8934226] objClass1 ClassObject objClass2 ClassObject objClass3 NSKVONotifying_ClassObject 2021-05-04 10:54:32.415562 0800 ClassDemo[28990:8934226] objClass1 0x10fea3550 objClass2 0x10fea3550 objClass3 0x600001300240
第三个值变成了NSKVONotifying_ClassObject
在开发中是不会手动去 alloc一个元类对象 可以通过object_getClass函数获取class的isa类取之 代码如下
- (void)fetchMetaClassWithClassObject:(ClassObject *)clsObj { //1. 获取一个对象的isa Class objIsa object_getClass(clsObj); //获取元类对象 Class metaClass object_getClass(objIsa); NSLog( \n metaClass %p \n metaClass % , metaClass, NSStringFromClass(metaClass)); }
会发现 元类还是当前的Class 但是是另一个对象地址
其次 不管是class对象还是元类对象 其类型都是Class 说明在内存结构上是一致的 但是其包含的信息含义是不一样的 其用途也不一样
image
以上的三种对象是如何关联起来的呢 是通过isa关联的:
instance对象的isa的值是class对象 class对象的isa的值是meta-calss对象
既然实例方法是存在于class对象中 那么当给一个instance对象发送消息的时候 是如何找到具体的实现方法的呢
当调用实例方法的时候 通过instance对象中的isa找到class 找到对应的实例方法的实现
同理 类方法的调用也是一样的
当调用类方法时 通过class对象的isa指针找到meta-class 并找到对应的类方法实现
相关文章
- iOS—如何申请苹果公司开发者账号流程详细图文介绍(包括邓白氏编码的申请方法详细介绍)
- iOS - isa、superclass指针,元类superclass指向基类本身(下)
- iOS开发transform的使用
- 李洪强iOS开发之-sql数据库的使用
- iOS 开发如何入门
- iOS开发之duplicate symbols for architecture x86_64错误
- 李洪强经典面试题30-iOS应用性能调优的25个建议和技巧
- iOS开发UI篇—无限轮播(新闻数据展示)
- iOS开发拓展篇—UIDynamic(捕捉行为)
- 李洪强iOS开发之【Objective-C】09-空指针和野指针
- react-native 可滑动日历,支持ios/android
- react-native-easy-toast, 一款简单易用的 Toast 组件,支持 Android&iOS.