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函数;

线


相关文章
|
C语言 索引
09-iOS之load和initialize底层调用原理分析
09-iOS之load和initialize底层调用原理分析
90 0
|
2月前
|
JavaScript 前端开发 开发者
探索yocto-queue库:替代数组的实现原理与方法
在需要高性能队列结构的场景下,yocto-queue提供了一个轻量级且高效的解决方案。它的实现原理优雅且有效,使得在实际应用中,特别是在性能敏感的环境下,成为了数组的一个强大替代者。通过减少性能开销,yocto-queue使得JavaScript开发者能够构建更快、更可靠的应用程序,从而提高用户体验和应用性能。
43 2
|
缓存 前端开发 Java
【Netty官方文档翻译】引用计数对象(reference counted objects)
【Netty官方文档翻译】引用计数对象(reference counted objects)
83 0
|
存储 开发工具 C++
08-OC底层原理之Category实现原理
08-OC底层原理之Category实现原理
53 0
|
设计模式 Java Python
简述Python类中的 __init__、__new__、__call__ 方法
简述Python类中的 __init__、__new__、__call__ 方法
104 0
|
存储 算法 安全
iOS-底层原理 02:alloc & init & new 源码分析
iOS-底层原理 02:alloc & init & new 源码分析
142 0
iOS-底层原理 02:alloc & init & new 源码分析
|
存储 缓存 算法
iOS-底层原理 11:objc_class 中 cache 原理分析
iOS-底层原理 11:objc_class 中 cache 原理分析
118 0
iOS-底层原理 11:objc_class 中 cache 原理分析
|
iOS开发
iOS-底层原理 04:NSObject的alloc 源码分析
iOS-底层原理 04:NSObject的alloc 源码分析
130 0
iOS-底层原理 04:NSObject的alloc 源码分析
|
存储 缓存 iOS开发
iOS底层原理:OC对象底层探索之alloc初探(二)
简介: iOS开发的小伙伴们对 [XXX alloc] init] 都不陌生,可以说 alloc 和 init 贯穿我们整个的开发过程中。那么在OC对象的底层,到底做了哪些操作呢?今天我们就来探索一下 alloc 底层的工作流程。
iOS底层原理:OC对象底层探索之alloc初探(二)
|
iOS开发
iOS底层原理:OC对象底层探索之alloc初探(一)
iOS开发的小伙伴们对 [XXX alloc] init] 都不陌生,可以说 alloc 和 init 贯穿我们整个的开发过程中。那么在OC对象的底层,到底做了哪些操作呢?今天我们就来探索一下 alloc 底层的工作流程。
iOS底层原理:OC对象底层探索之alloc初探(一)