美文网首页
OC的本质

OC的本质

作者: 海辰 | 来源:发表于2020-03-11 09:59 被阅读0次

    1 objective-c ->c\c++->汇编语言(不同的平台指令不同,显示的代码不同)->机器语言。

    2 .m文件转换成c++

    命令行:xcrun -sdk iphoneos(平台) clang -arch(架构) arm64 -rewrite-objc  OC源文件 - 0 输出的CPP文件。

    3 模拟器 i386 32bit(armv7) 64bit (arm64)

    struct NSObject_IMPL {

     Class isa; // 8个字节

    }

    // 指针

    typedef struct objc_class* Class;

    OC的指针转换成C的指针 (__bridge const void *)

    // 获取NSObject 实例对象的成员变量所占用的内存大小 >> 8个字节。

    class_getInstanceSize([NSObject class]) // 内存对齐过的成员变量的大小

    // 源码

    // class's ivar size rounded up to pointer-size boundary

    uint32_t align

    1 系统分配了16个字节给NSObject对象(通过malloc_size函数)

    获得obj指针所指向内存的大小 >> 16

    malloc_size((__bridge const void*)obj));

    但是NSObject对象内部只使用了8个字节的空间(64bit).

     2 内存对齐:结果体的最终大小必须是最大成员大小的倍数

     3 alloc 出来的实列对象不存储方法。

    4  

    struct NSObject_IMP{

    Class isa

    }

    struct Person_IMPL

    {

    struct NSObject_IMP NSOBJECTPERSON

    int  _age;

    }

    @interface Person:NSobject

    {

    int age;

    }

    5  创建一个实列对象,至少需要多些内存

    #import <objc/runtime.h>

    class_getInstanceSize([NSObject class]);

    6 创建一个实列对象,实际分配了多小内存

    #import <malloc/malloc.h>

    malloc_size((__bridge const void*)obj);

    sizeof() 类型的大小 运算符 编译时确定

    OC对象的分类

    instance 对象(实列对象)

    isa指针

    其他的成员变量

    class对象(类对象)

    他们都是同一个对象,每一个类在内存中有🐧只有一个class对象

    isa 指针

    superclass 指针

    类的属性信息(@property),

    类的对象方法信息(instance method)

    类的协议信息(protocal),类的成员变量信息(ivar)

    meta-class 对象(元类对象)(meta-data)(元数据)

    Class objectMetaClass = get_getClass([NSObject class]); //runtime api

    1 objectMetaClass 是NSObject的meta-class对象(元类对象)

    2 每个类在内存中有且只有一个meta-class对象

    3 meta-class对象和class对象的内存结构是一样的,但是用途不一样,在内存存储的信息不同:

    isa 指针

    superclass 指针

    类的类方法信息(class method)

    ...

    Class object_getClass(id obj) {

    // 如果obj是一个instance 对象,返回class对象

    // 如果是class对象,返回meta-class对象

    // 如果是meta-class对象 返回nsobject的meta-class对象

    if(obj) return obj->getIsa();

    else return nil;

    }

    // 直接返回类对象

     Class objc_getClass(const *char name) {

    //

    // 类方法

    objc_msgSend([MJPerson class],@selector());

    // 实列方法

    objc_msgSend(person,@selector());

    1 从64bit开始,实列对象的isa需要进行一次位运算才能算出class的地址。

    struct objc_class:objc_object {

    class supperClass;

    cache_t cache;

    class_data_bites bits;

    }

    对象的isa的指针指向哪里

    1 instance对象的isa指向class对象

    2 class对象的isa指向meta-class对象

    3 meta-class对象的isa指向积累的meta-class对象

    OC的类信息存放在哪里

    对象方法,属性,成员变量,协议信息存放在class对象中

    类方法存放在meta-class对象中

    成员变量的具体值,存放在instance对象。

    类对象和元类对象在程序开启的时候就加载进入内存,只保存一份。当程序退出的时候销毁内存。

    相关文章

      网友评论

          本文标题:OC的本质

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