01-OC对象的底层实现之alloc、init、new源码解读

简介: 01-OC对象的底层实现之alloc、init、new源码解读

1. OC对象的底层实现?

Objective-C的面向对象都是基于C/C++的数据结构实现的,接下来我们来探究一下OC对象的底层实现;

1.1 NSObject的底层实现

首先在main函数里面定义一个obj对象:

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        // insert code here...
        NSLog(@"Hello, World!");
        NSObject *obj = [[NSObject alloc] init];
    }
    return 0;
}

将main.m转换为c++代码,通过如下命令:


xcrun -sdk iphoneos clang -arch arm64 -F Foundation.framework -rewrite-objc main.m -o main.cpp

查看main.cpp文件,会发现这样一个结构体:

struct NSObject_IMPL {
  Class isa;
};

我们查看NSObject对象的声明:

@interface NSObject <NSObject> {
    Class isa  OBJC_ISA_AVAILABILITY;
}

通过对比我们会发现一个NSObject对象实际上就是一个结构体,通过objc的源码看到Class的定义如下,实际上它就是一个指向结构体的指针,故isa是一个指针类型;


typedef struct objc_class *Class;

1.2 自定义对象的底层实现

我们定义一个对象

@interface Person : NSObject {
    @public
    int age;
    int height;
}
@end
@implementation Person
@end

通过1.1中的命令,再来看一下它的底层实现:

struct Person_IMPL {
  struct NSObject_IMPL NSObject_IVARS;
  int age;
  int height;
};

而NSObject_IMPL的实现如下:

struct NSObject_IMPL {
  Class isa;
};

则Person的最终实现可以理解为:

struct Person_IMPL {
  Class isa;
  int age;
  int height;
};

使用如下代码验证一下p所指向的对象就是Person_IMPL这个结构体,从打印结果可以看出确实如此

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        Person *p = [[Person alloc] init];
        p->age = 4;
        p->height = 10;
        struct Person_IMPL *p_imp = (__bridge struct Person_IMPL *)(p);
        NSLog(@"%d", p_imp->age);//打印结果:4
    }
    return 0;
}

1.3 自定义对象的嵌套底层实现


@interface Person : NSObject {
    @public
    int age;
}
@end
@implementation Person
@end
@interface Student : Person {
    @public
    int height;
}
@end
@implementation Student
@end

通过1.1中的命令,再来看一下它的底层实现:

struct NSObject_IMPL {
    Class isa;
};
struct Person_IMPL {
    struct NSObject_IMPL NSObject_IVARS;
    int age;
};
struct Student_IMPL {
    struct Person_IMPL Person_IVARS;
    int height;
};

而Student最终可以理解为

struct Student_IMPL {
    Class isa;
    int age;
    int height;
};

2.  alloc源码解读

2.1 创建一个Person对象,其中Person类中无任何成员变量

2.2 进入到alloc方法的源码实现中

2.3 跳转到_objc_rootAlloc函数中

2.4 callAlloc实现


hasCustomAWZ为是否实现了allocWithZone方法

// class or superclass has default alloc/allocWithZone: implementation
// Note this is is stored in the metaclass.
#define FAST_CACHE_HAS_DEFAULT_AWZ    (1<<14)
bool hasCustomAWZ() const {
    return !cache.getBit(FAST_CACHE_HAS_DEFAULT_AWZ);
}

2.5 执行_objc_rootAllocWithZone方法

2.6 执行_class_createInstanceFromZone方法

先看size = cls->instanceSize(extraBytes),其中extraBytes为0,这里执行到了cache.fastInstanceSize(extraBytes),如果走到了下面会看到如果分配的size小于16的话,size会强制设置为16


接着看fastInstanceSize之后会执行到align16函数,16字节对齐算法,会发现size就是为16;

实际上类所分配的实际内存最低都为16的倍数,这一点是从操作系统的层面去考虑的,为了加快cpu的读写速度,另一方面,也为了避免数据错乱,如果感兴趣的可以下载libmalloc源码自行查看;

接下来会调用calloc以及isa的处理等,这里不再深入分析,至此整个alloc流程结束;

3. init源码解读

调用init方法(实例方法的init)接着会来到下方,然后整个流程结束

我们会发现整个流程什么都没做,苹果这样设计的目的是什么呢?实际上这是苹果的一种设计模式就是为了将来我们在使用的时候,可以在重写init的内部做一些自定义的操作;

- (instancetype)init {
    if (self = [super init]) {
        //...
    }
    return self;
}

4. new源码解读

调用new的时候,会发现内部调用了callAlloc又调用了init函数,会发现又来到了callAlloc函数,接下来的整个过程和alloc过程一致,实际上调用new就相当于调用了alloc - init函数;

线


相关文章
|
JavaScript 前端开发 Shell
用shell脚本写一个坦克大战的游戏的思路
用shell脚本写一个坦克大战的游戏思路
532 1
|
存储 Kubernetes 调度
【K8S系列】第二讲:Pod入门
【K8S系列】第二讲:Pod入门
370 0
|
3月前
|
存储 编解码 并行计算
【快速傅里叶变换FFT、窗函数法、希尔伯特-黄变换、小波变换】电力系统同步相量计算研究(Matlab代码实现)
【快速傅里叶变换FFT、窗函数法、希尔伯特-黄变换、小波变换】电力系统同步相量计算研究(Matlab代码实现)
182 6
|
存储 安全 算法
【JAVA】HashMap扩容性能影响及优化策略
【JAVA】HashMap扩容性能影响及优化策略
|
机器学习/深度学习 数据采集 TensorFlow
使用Python实现深度学习模型:智能环境监测与预警
【8月更文挑战第11天】 使用Python实现深度学习模型:智能环境监测与预警
1347 2
|
开发框架 Dart API
Flutter引擎工作原理:深入解析FlutterEngine
【4月更文挑战第26天】FlutterEngine是Flutter应用的关键,负责Dart代码转换为原生代码,管理应用生命周期、渲染和事件处理。它初始化Flutter运行时环境,加载并编译Dart代码,创建渲染树,处理事件并实现跨平台兼容。通过理解其工作原理,开发者能更好地掌握Flutter应用内部机制并优化开发。随着Flutter生态系统发展,FlutterEngine将持续提供强大支持。
1103 1
|
Web App开发 数据采集 编解码
html/SEO:mate/百度规则下写好mate标签的重要性
html/SEO:mate/百度规则下写好mate标签的重要性
291 0
|
Linux Docker 容器
阿里云安装docker教程
阿里云安装docker教程
2256 0
|
机器学习/深度学习 编解码 移动开发
YOLOv8改进 | 2023 | FocusedLinearAttention实现有效涨点
YOLOv8改进 | 2023 | FocusedLinearAttention实现有效涨点
367 0
YOLOv8改进 | 2023 | FocusedLinearAttention实现有效涨点

热门文章

最新文章