美文网首页
iOS底层学习1 -- oc对象底层原理1

iOS底层学习1 -- oc对象底层原理1

作者: 恋空K | 来源:发表于2020-04-24 11:33 被阅读0次

    画圈的地方是一个字节。上面截图用的是16进制,一个16进制位,代表4个二进制位。两个16进制位代表8个二进制位。一个字节由8个二进制位组成
    如果一个结构体里面就一个成员:比如
    struct NSObject_IMPL {
    Class isa; —> isa 占8个字节----指针在64的平台中是占8个字节
    }
    因为这个struct NSObject_IMPL 结构体只有一个成员
    所以这个结构体也只占8个字节

    继承关系中,父类的成员变量放前面,自己的成员变量后后面,如截图
    同一个结构体里面的成员,内存地址是连续的 因为 isa占8个字节,所有_no的地址是 0x100400118
    结构体最前面的那个成员的地址值,就是结构体的地址值。就好比数组首元素的地址,就是数组的地址
    iOS 的CPU是小端模式,所以从内存中读取 04 00 00 00 读取出来就是0x00000004
    总结,对象底层是一个结构体,该结构体首先包含父类的结构体的现实,在包含自己的成员变量

    一个oc对象系统最少会给它分配16个字节。
    内存对齐:就算没有oc的至少16个字节的规定,内存对齐有一条规则,结构体的大小必须是最大成员大小的倍数

    @interface Person : NSObject
    {
    NSInteger a;//占4个自己
    }
    NSObject *obj = [[NSObject alloc] init];
    NSLog(@"%zd",class_getInstanceSize([Person class]));
    //获取NSObject实例对象的成员变量所占用的内存大小
    NSLog(@"%zd",class_getInstanceSize([NSObject class]));
    NSLog(@"%zd",malloc_size((__bridge const void *)person));
    //获取obj指针所指向内存大小
    NSLog(@"%zd",malloc_size((__bridge const void *)objc));
    2020-04-24 22:42:52.547269+0800 PrettyRuler[63943:1150801] 16
    2020-04-24 22:42:52.547447+0800 PrettyRuler[63943:1150801] 8
    2020-04-24 22:42:52.547539+0800 PrettyRuler[63943:1150801] 16
    2020-04-24 22:42:52.547627+0800 PrettyRuler[63943:1150801] 16
    malloc_size 返回的是系统实际分配给对象的内存大小。
    class_getInstanceSize返回的是内存对齐后的结构体的大小(返回的是一个类创建的实例对象所占用的内存空间的大小)

    Person *person = [Person alloc] init];
    我们创建出来的实例对象,alloc出来的这种实例对象只存有它的成员变量,方法是不会放到实例对象里面的。成员变量每个实例对象都有一份,每个实例对象只要放自己特有的东西就好了。而方法都是一样的,所以只要一份就够了,

    面试题:一个NSOject对象占用多少内存?
    1.系统分配了16个字节给NSObject 对象(通过malloc_size函数获得)
    2.但NSObject对象内部只使用了8个字节的空间(64bit环境下,可以通过clss_getInstanceSize函数获得)

    相关文章

      网友评论

          本文标题:iOS底层学习1 -- oc对象底层原理1

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