1、一个NSObject对象占用多少内存?
系统分配了16个字节给NSObject对象(通过malloc_size函数获得);
但NSObject对象内部只使用了8个字节的空间(64bit环境下,可以通过class_getInstanceSize函数获得)。
相关知识点:
//将oc文件重写为cpp文件:
clang -rewrite-objc main.m -o main.cpp
//将oc文件重写为运行在 iphone 上面的架构为 arm64 的cpp文件:
xcrun -sdk iphoneos clang -arch arm64 -rewrite-objc main.m -o main-arm64.cpp
// NSObject 在 oc 头文件中的定义
@interface NSObject {
Class isa;
}
//对应的 C++ 的代码是:
struct NSObject_IMPL {
Class isa;
};
//结论1: 可以看出,OC类的底层实现是C++的结构体。
//ps: typedef struct objc_class *Class;
//Class是一个结构体指针。
//猜测:指针在64位环境中占8个字节,因为一个 NSObject 对象只有一个成员为Class类型的isa,所以一个 NSObject 对象也占8个字节。
//验证:
//导入头文件:
#import
#import
NSObject *obj = [[NSObject alloc] init];
//获取 NSObject 类的实例对象的成员变量在内存中占用空间的大小 >> 8
NSLog(@"%zd",class_getInstanceSize([NSObject class]));
//获取指针obj 所指向的内存空间的大小 >> 16
NSLog(@"%zd",malloc_size((__bridge const void *)(obj)));
//为什么打印出来的结果不一样呢?
//通过 https://opensource.apple.com/tarballs/,查看苹果源码。苹果源码中 class_getInstanceSize的源码实现
size_t class_getInstanceSize(Class cls)
{
if (!cls) return 0;
return cls->alignedInstanceSize();
}
//alignedInstanceSize :苹果给的注释是:Class's ivar size rounded up to a pointer-size boundary。即成员变量的大小,也就是isa指针的大小。即在arm64环境中是占8个字节。
//allocWithZone源码
_objc_rootAllocWithZone(Class cls, malloc_zone_t *zone)
{
id obj;
if (fastpath(!zone)) {
obj = class_createInstance(cls, 0);
} else {
obj = class_createInstanceFromZone(cls, 0, zone);
}
if (slowpath(!obj)) obj = _objc_callBadAllocHandler(cls);
return obj;
}
_class_createInstanceFromZone(Class cls, size_t extraBytes, void *zone)
{
void *bytes;
size_t size;
// Can't create something for nothing
if (!cls) return nil;
// Allocate and initialize
size = cls->alignedInstanceSize() + extraBytes;
// CF requires all objects be at least 16 bytes.
if (size
2、字节与十六进制、二进制的关系
一个字节是由两位16进制数组成。
十六进制一般用数字0到9和字母A到F(或a ~ f)表示,其中:A~F表示10~15,这些称作十六进制数字。
十六进制数转换在二进制数:把每一个十六进制转换成4位的二进制数,就得到一个二进制数。
十六进制数字与二进制数字的对应关系如下:
二进制 0000 对应十六进制 0
二进制 0001 对应十六进制 1
二进制 0010 对应十六进制 2
二进制 0011 对应十六进制 3
二进制 0100 对应十六进制 4
二进制 0101 对应十六进制 5
二进制 0110 对应十六进制 6
二进制 0111 对应十六进制 7
二进制 1000 对应十六进制 8
二进制 1001 对应十六进制 9
二进制 1010 对应十六进制 A
二进制 1011 对应十六进制 B
二进制 1100 对应十六进制 C
二进制 1101 对应十六进制 D
二进制 1110 对应十六进制 E
二进制 1111 对应十六进制 F
因此,1个16进制位对应4个二进制位,2个16进制位对应8个二进制数位,即1个字节。如上图所示,红框代表一个字节,蓝框代表16个字节。
3、常用LLDB指令
print、p : 打印
po:打印对象
读取内存
memory read/数量格式字节数 内存地址
x/数量格式字节数 内存地址
x/3xw 内存地址
格式
x是16进制,f是浮点,d是10进制
字节大小
b:byte 1字节,h: half word 2字节
w:word 4字节,g: giant word 8字节
改写内存
memory write 内存地址 修改值
memory write 内存地址 8
4、c++ 与 oc 代码互转
struct Student_IMPL {
Class isa;
int _no;
int _age;
};
@interface Student : NSObject {
@public
int _no;
int _age;
}
@end
@implementation Student
@end
typedef struct objc_class *Class;
int main(int argc, char * argv[]) {
@autoreleasepool {
Student *stu = [[Student alloc] init];
stu->_no = 4;
stu->_age = 5;
struct Student_IMPL *stuIMPL = (__bridge struct Student_IMPL *)stu;
NSLog(@"no is %d,age is %d",stuIMPL->_no,stuIMPL->_age);
}
return 0;
}
【信息由网络或者个人提供,如有涉及版权请联系COOY资源网邮箱处理】
暂无评论内容