先看1个问题
1、一个NSObject对象占用多少内存?
一、NSObject 类
oc代码的底层是C/C++代码
oc的面向对象其实都是基于C/C++的数据结构实现的:
image.png
怎么将oc代码转换为C/C++代码?
转成iOS平台的代码
xcrun -sdk iphoneos clang -arch arm64 -rewrite-objc oc源文件 -o 输出的cpp文件
转换一下main.m文件
1、打开终端,cd 到main.md的文件所在文件夹
2、运行命令 xcrun -sdk iphoneos clang -arch arm64 -rewrite-objc main.m -o main-arm64.cpp
image.png
最后生成一个.cpp文件
image.png
main函数变成了下面的代码
int main(int argc, char * argv[]) {
NSString * appDelegateClassName;
/* @autoreleasepool */ { __AtAutoreleasePool __autoreleasepool;
appDelegateClassName = NSStringFromClass(((Class (*)(id, SEL))(void *)objc_msgSend)((id)objc_getClass("AppDelegate"), sel_registerName("class")));
NSObject *obj = ((NSObject *(*)(id, SEL))(void *)objc_msgSend)((id)((NSObject *(*)(id, SEL))(void *)objc_msgSend)((id)objc_getClass("NSObject"), sel_registerName("alloc")), sel_registerName("init"));
}
return UIApplicationMain(argc, argv, __null, appDelegateClassName);
}
也可以直接点进去看
@interface NSObject <NSObject> {
Class isa OBJC_ISA_AVAILABILITY;
}
所以 [[NSObject alloc] init] 底层实现是长得这样子,就是一个结构体,一个结构体里就只有一个指针,所以占8个字节
struct NSObject_IMPL {
Class isa;//占8个字节
};
图示
image.png
二、自定义的类
-如果是一个自定义的类Student
#import <objc/runtime.h>
#import <malloc/malloc.h>
@interface Student : NSObject
{
@public
int _no;//4
int _age;//4
int _grade;//4
}8+12=20 24
多出来的4个字节,好像是计算机内存对齐产生的
@end
@implementation Student
@end
int main(int argc, char * argv[]) {
NSString * appDelegateClassName;
@autoreleasepool {
appDelegateClassName = NSStringFromClass([AppDelegate class]);
Student *xiaoming = [[Student alloc] init];
xiaoming->_age = 4;
xiaoming->_no = 5;
xiaoming->_grade = 98;
NSLog(@"Student类实例对象的成员变量所占用的大小:🍎%zd",class_getInstanceSize([Student class]));
NSLog(@"xiaoming指针所指向内存的大小:🍎%zd",malloc_size((__bridge const void *)(xiaoming)));
}
return UIApplicationMain(argc, argv, nil, appDelegateClassName);
}
image.png
又加了几个成员变量,打出的结果不一样
student对象的本质.png假如一个Person对象继承自NSobject,Student 继承自Person,那么Person 和Student分别占用的内存是多少?
image.png
Student应该占用20个字节,为啥最后是16个字节,这是因为内存对齐造成的, _no的4个字节占用了Person空出来的4个字节
三、另外一种方式窥探
Class 是一个指针
现在我们来看第一个问题
#import <objc/runtime.h>
#import <malloc/malloc.h>
int main(int argc, char * argv[]) {
NSString * appDelegateClassName;
@autoreleasepool {
appDelegateClassName = NSStringFromClass([AppDelegate class]);
NSObject *obj = [[NSObject alloc] init];
NSLog(@"NSObject类实例对象的成员变量所占用的大小:8字节🍎%zd",class_getInstanceSize([NSObject class]));
NSLog(@"obj指针所指向内存的大小:16字节🍎%zd",malloc_size((__bridge const void *)(obj)));
}
return UIApplicationMain(argc, argv, nil, appDelegateClassName);
}
image.png
结果:
image.png
感觉红框中的其实就是 isa 指针
现在可以回答开篇的第1个问题:
一个指针变量所占用的大小(64bit环境下,8个字节,32bit环境下,4个字节)
- 常用LLDB指令
print 、p 打印
po 打印对象
memory read 读取内存地址
Printing description of obj:
<NSObject: 0x60000364c130>
(lldb) p obj
(NSObject *) $7 = 0x000060000364c130
(lldb) po obj
<NSObject: 0x60000364c130>
(lldb) memory read 0x60000364c130
0x60000364c130: 00 2d be 89 ff 7f 00 00 00 00 00 00 00 00 00 00 .-..............
0x60000364c140: c8 fa a5 87 ff 7f 00 00 e4 85 22 6c 42 ae 26 a2 .........."lB.&.
(lldb)
网友评论