一个OC对象的旅程
导语:一个初级iOS开发者一定很好奇一个OC对象创建出来到底是怎么样的,今天我们就来简单看一下(如果有误请留言指正,非常感谢)
- 一个对象创建出来,在底层关系走向如下:
例如: FRPerson继承自NSObject
FRPerson *person = [[FRPerson alloc] init];
复制代码
| 一个对象的旅程 |
|---|
| person是一个局部变量(内存在栈中) |
| person变量是一个指针,指向person实例(instance)对象(内存在堆里) |
| person实例对象里有isa指针,指向FRPerson类(class)对象(内存在全局区) |
| FRPerson类对象(class)里也有isa指针,指向元类(meta-class)对象(内存在全局区) |
| FRPerson元类对象的isa指向基类元类类对象(NSObject的元类对象)(内存在全局区) |
| 基类的元类对象的isa指针指向自己 |
实例对象可以创建多个,创建一个就会通过alloc在堆里申请一份新的内存
类对象,元类对象在内存中分别只有一份,获取多少次都是同一个地址
实例对象 类对象 元类对象
-
具体内存结构
-
实例对象(instance)
| instance |
|---|
| isa指针(前8个字节) |
| 成员变量的值 |
| … |
- 类对象 (class)
| class |
|---|
| isa指针(前8个字节) |
| superclass指针(8个字节) |
| 属性信息 |
| 对象方法信息 |
| 协议信息 |
| 成员变量信息 |
| … |
- 元类对象(meta-class)
| meta-class |
|---|
| isa指针(前8个字节) |
| superclass指针(8个字节) |
| 类方法信息 |
| … |
- 获取 实例对象 类对象 元类对象
导入头文件
#import <objc/runtime.h>
//实例对象
Person *person = [[Person alloc] init];
//类对象
Class personClass = [person class];
//元类对象
Class metaClass = object_getClass(personClass);
BOOL isMetaClass = class_isMetaClass(metaClass);
NSLog(@"%p,%p,%p,%d",person,personClass,metaClass,isMetaClass);
//0x100494140,0x100008100,0x1000080d8,1
复制代码
object_getClass函数参数如果传入的是实例对象,返回的就是类对象,传入类对象返回的就是元类对象
类对象和元类对象都是Class类型,也就是说他们的类型是一样的,只是里面存储的信息不同
class_isMetaClass判断是否是一个元类对象
superclass指针
| superclass指针 |
|---|
| 类对象的superclass指针指向父类的类对象,一直到基类,基类的superclass为nil |
| 元类对象的superclass 指向父类的元类对象,一直到基类元类对象,但是基类元类对象的superclass会指向基类的类对象 |
注意:根据superclass指针最终走向,如果一个类调用一个类方法,一直找不到,最终会找到基类的类对象中,而基类类对象保存的方法是基类的对象方法,如果有个同名的对象方法,系统会调用这个方法。(结果就是一个类调用了对象方法)
从中得出一个推论:runtime运行时是不会根据是对象方法,类方法来调用方法的;对象方法,类方法只是确定他们的存放位置。
网上找到的一个关系图,非常的形象:

- 下一篇,我们说一下方法是怎么调用的。
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END























![[桜井宁宁]COS和泉纱雾超可爱写真福利集-一一网](https://www.proyy.com/skycj/data/images/2020-12-13/4d3cf227a85d7e79f5d6b4efb6bde3e8.jpg)

![[桜井宁宁] 爆乳奶牛少女cos写真-一一网](https://www.proyy.com/skycj/data/images/2020-12-13/d40483e126fcf567894e89c65eaca655.jpg)