美文网首页
OC对象的本质

OC对象的本质

作者: MeliodasLy | 来源:发表于2018-06-09 18:11 被阅读17次

    Objective-C的本质

    我们平时编写的Objective-C代码,底层实现其实都是C\C++代码
    Objective-C -> C\C++ -> 汇编语言 -> 机器语言
    所以Objective-C的面向对象都是基于C\C++的数据结构实现的

    • 思考:Objective-C的对象、类主要是基于C\C++的什么数据结构实现的?
      • 结构体

    将Objective-C代码转换为C\C++代码

    xcrun -sdk iphoneos clang -arch arm64 -rewrite-objc OC源文件 -o 输出的CPP文件
    
    • 思考:一个OC对象在内存中是如何布局的
    • NSObject的底层实现
    // NSObject Implementation
    struct NSObject_IMPL {
        Class isa; // 8个字节,32bit4个字节(常识:在64位下,指针占8个字节)
    };
    typedef struct objc_class *Class;// 结构体里面Class的内部实现
    NSObject *obj = [[NSObject alloc] init];
    

    本质如下图所示


    image.png

    一个NSObject对象占用多少内存

    • 系统分配了16个字节给NSObject对象(通过malloc_size函数获得)
    • 但NSObject对象内部只使用了8个字节的空间(64bit环境下,可以通过class_getInstanceSize函数获得)

    可以根据objc/runtime.h里面的方法去获取

    NSObject *obj = [[NSObject alloc] init];
    // 获取NSObject类的实例对象的成员变量所占用的大小 >>8
    NSLog(@"%zd",class_getInstanceSize([NSObject class]));
    

    另外可以根据malloc/malloc.h里面的方法去获取

    NSObject *obj = [[NSObject alloc] init];
    // 获取obj指针所指向内存的大小 >> 16
    NSLog(@"%zd",malloc_size((__bridge const void *)obj));
    
    2个容易混淆的函数

    创建一个实例对象,至少需要多少内存?

    #import <objc/runtime.h>
    class_getInstanceSize([NSObject class]);
    

    创建一个实例对象,实际上分配了多少内存?

    #import <malloc/malloc.h>
    malloc_size((__bridge const void *)obj);
    

    内存对齐:结构体的大小必须是最大成员大小的倍数
    另外,苹果本身也会进行内存对齐的处理,分配的内存一定是16的倍数,最大为256

    最后,本人仍会深入学习,更新更多文章

    相关文章

      网友评论

          本文标题:OC对象的本质

          本文链接:https://www.haomeiwen.com/subject/sjxxeftx.html