1、OC的对象、类主要是C\C++的什么数据结构实现的?
- 结构体
2、把OC代码转换成c++代码
- iPhone架构分类:
模拟器 | i386架构 |
---|---|
32bit真机 | armv7 |
64bit真机 | arm64 |
- 指令:
直接转换:
clang -rewrite-objc main.m -o main.cpp
iPhone平台转换:
xcrun -sdk iphoneos clang -arch arm64 -rewrite-objc main.m -o main.cpp
- 在main.cpp文件中,搜索NSObject_IMPL可以发现
struct NSObject_IMPL {
Class isa; // 指针 8个字节
};
- 内存大小
// 先导入头文件如下
#import <Foundation/Foundation.h>
#import <objc/runtime.h>
#import <malloc/malloc.h>
int main(int argc, const char * argv[]) {
@autoreleasepool {
NSObject *obj = [[NSObject alloc] init];
// 获取NSObject类的实例对象的大小
NSLog(@"实例对象的大小-%zd",class_getInstanceSize([NSObject class]));
// 获取obj指针指向内存的大小
NSLog(@"指针指向内存的大小-%zd",malloc_size((__bridge const void *)(obj)));
NSLog(@"Hello, World!");
/**打印结果如下:
2021-12-23 19:31:15.893600+0800 01-oc本质[1512:18220] 实例对象的大小-8
2021-12-23 19:31:15.893932+0800 01-oc本质[1512:18220] 指针指向内存的大小-16
2021-12-23 19:31:15.893962+0800 01-oc本质[1512:18220] Hello, World!
*/
}
return 0;
}
那么内存的大小到底是多少呢?
- 下载最新的苹果objc开源代码:https://opensource.apple.com/tarballs/objc4/
- 全局搜索“size_t instanceSize”,可以看到这段源码
size_t instanceSize(size_t extraBytes) {
size_t size = alignedInstanceSize() + extraBytes;
// CF requires all objects be at least 16 bytes.
// 注释大概意思是说,所有的对象最少要16个字节
if (size < 16) size = 16;
return size;
}
**
问题:一个NSObject对象占用多少内存?
1、系统分配了16个字节NSObject对象
2、但是NSObject对象内部只使用了8个字节的空间
**
3、进一步窥探内存细节
-
运行XCode,打断点
-
设置-- Debug–> Debug Workflow --> Always Show Disassembly
-
把对象地址打印出来,可以发现只有前面8个字节有内容,后面8个字节是空的
4、通过LLDB指令窥探细节
- 常用LLDB指令
- (大小端模式)苹果一般是小端模式:
2019 = 2*10^3+0*10^2+1*10^1+9*10^0
可以称高位对应的权重(10^3)大,低位对应的权重小。
小端就是先存储权重小的,大端就是先存储权重大的
举例:0x1234
不要记忆高地址,低地址,看下图
(或者记住:正常人写阿拉伯数字就是大端模式,从左往右开始写)
从左到右,地址从低到高
小端模式 | 4 | 3 | 2 | 1 |
---|---|---|---|---|
大端模式 | 1 | 2 | 3 | 4 |
– | 低地址 | – | – | 高地址 |
-- print、p : 打印
-- po : 打印对象
-- 读取内存
1、mermory read/数量+格式+字节数 内存地址
例如:x/3xw 0x10010
修改内存中的值
memory write 内存地址 数值
mermory write 0x00000010 10
/*
(lldb) memory read 0x0000000100605230
0x100605230: 89 50 60 80 ff ff 1d 01 00 00 00 00 00 00 00 00 .P`.............
0x100605240: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
(lldb) memory write 0x0000000100605234 7
(lldb) memory read 0x0000000100605230
0x100605230: 89 50 60 80 07 ff 1d 01 00 00 00 00 00 00 00 00 .P`.............
0x100605240: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
可以看到内存值由 89 50 60 80 ff
改为了 89 50 60 80 07
*/
2、格式:x 16进制, f 浮点数, d 10进制
3、字节大小:
b: byte 1字节
h: half word 2字节
w: word 4字节
g: giant word 8字节
/* 打印结果
(lldb) p obj
(NSObject *) $1 = 0x0000000100605230
(lldb) po obj
<NSObject: 0x100605230>
(lldb) memory read 0x0000000100605230
0x100605230: 89 50 60 80 ff ff 1d 01 00 00 00 00 00 00 00 00 .P`.............
0x100605240: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
(lldb) x 0x0000000100605230
0x100605230: 89 50 60 80 ff ff 1d 01 00 00 00 00 00 00 00 00 .P`.............
0x100605240: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
(lldb) x/3xg 0x0000000100605230
0x100605230: 0x011dffff80605089 0x0000000000000000
0x100605240: 0x0000000000000000
(lldb) x/3xh 0x0000000100605230
0x100605230: 0x5089 0x8060 0xffff
(lldb) x/3xw 0x0000000100605230
0x100605230: 0x80605089 0x011dffff 0x00000000
(lldb) x/3xb 0x0000000100605230
0x100605230: 0x89 0x50 0x60
(lldb) x/4xw 0x0000000100605230
0x100605230: 0x80605089 0x011dffff 0x00000000 0x00000000
(lldb) x/4dw 0x0000000100605230
0x100605230: -2141171575
0x100605234: 18743295
0x100605238: 0
0x10060523c: 0
(lldb) x/4fw 0x0000000100605230
0x100605230: -8.8450982E-39
0x100605234: 2.9020014E-38
0x100605238: 0
0x10060523c: 0
(lldb)
*/
5、注意的地方
定义这样一个类
@interface Student : NSObject
{
@public
int _no;
int _age;
int _height;
}
@end
@implementation Student
@end
int main(int argc, const char * argv[]) {
@autoreleasepool {
NSLog(@"%zd", sizeof(struct Student_IMPL)); // 打印结果24
Student *stu = [[Student alloc] init];
NSLog(@"%zd", class_getInstanceSize([Student class])); // 打印结果24
NSLog(@"%zd", malloc_size((__bridge const void *)(stu))); // 打印结果32
}
return 0;
}
- 分配给stu对象的内存是32,实际使用的是24
- 因为在iOS系统里面,给对象分配的最少内存单位是16,所以说,对象的内存大小是16的倍数