关于对象与内存分析

(一)OC对象在底层中的布局

我们平时编写的Objective-C代码,在底层都是使用C/C++实现。
Objective-C -> C/C++ -> 汇编语言 -> 机器语言
我们定义个NSObject对象

NSObject *object = [[NSObject alloc] init];

使用终端命令将OC代码转换成iOS能支持的C/C++代码;

xcrun  -sdk  iphoneos  clang  -arch  arm64  -rewrite-objc  'OC源文件'  -o  '输出的CPP文件'

通过阅读转换后的.cpp文件,可以找到一个名为 NSObject_IMPL的结构体。分析结构体名字实际含义是 NSObject Implementation

struct NSObject_IMPL {
    Class isa; 
};

因此我们可以知道OC对象在底层的布局是一个结构体

(二)对象在内存中的占用大小

引入<objc/runtime.h>, 使用 class_getInstanceSize方法可获取NSObject实例对象的 成员变量 所占用的大小,可以观察到返回 8 个字节

class_getInstanceSize([NSObject class])

引入<malloc/malloc.h>, 使用malloc_size方法获取指针所指向的内存大小,可以观察到返回16个字节。

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

通过阅读Objc源码 可得知在alloc一个对象时,CoreFunction框架硬性规定分配内存空间不小于16个字节

1.png


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

 

(三)通过XCode工具分析内存

首先打印NSObject对象地址,通过工具ViewMemory查看。
可观察到前16个字节中,只有8个字节存在数据(存放isa指针)

2.png

 

(四)自定义类内存分析

定义Student类,初始化。通过重复之前步骤,可观察到底层实现。

struct Student_IMPL {
    Class isa;
    int _no;
    int _age;
};
@interface Student : NSObject
{
    @public
    int _no;
    int _age;
}
@end
@implementation Student
@end
int main(int argc, const char * argv[]) {
    @autoreleasepool {
        Student *stu = [[Student alloc] init];
        stu->_no = 4;
        stu->_age = 5;
        
        NSLog(@"%zd", class_getInstanceSize([Student class]));
        NSLog(@"%zd", malloc_size((__bridge const void *)stu));
    }
    return 0;
}

通过使用class_getInstanceSizemalloc_size方法可观察到占用16个字节存储空间。

3.png


使用ViewMemory查看前8个字节存放isa_no_age分别占用4个字节。

 

我们也可以使用LLDB指令打印相关地址信息,并且可使用memory write指令直接修改内存中的数据

4.png


可以观察到将_no中的值修改为了8

 

(五)继承类的内存占用分析

@interface Person : NSObject
{
    @public
    int _age;
}
@end

@implementation Person

@end

@interface Student : Person
{
    int _no;
}
@end

@implementation Student

@end

分析:Person类中isa指针占用8个字节,_age占用4个字节。通过CoreFunction框架硬性规定分配内存空间不小于16个字节。得知共占用16个字节。
但是即使无此硬性规定,通过内存对齐规则:结构体的最终大小,必须是最大成员的倍数。

Student类占用16个字节。isa占用8个字节,_age占用4个字节,剩余4个字节,被_no占用。



作者:GY1994
链接:https://www.jianshu.com/p/8e441aec3bbf
來源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值